1、static_cast(object)
相当于传统的C语言里的强制转换,能转换非指针类型类和变量
2、dynamic_cast(object)
只能转换具有父子关系的类指针,而且下行转换还不许包含多态(虚函数)
条件比较苛刻,执行效率不高
3、reinterpret_cast(object)
强制转换一切类型指针,无任何检查,正确性由程序员自己负责
指针和整数之间转换、指针之间转换(void*除外)只能用reinterpret_cast
整数之间转换可以只能用static_cast
void testGeneralType(void) //普通类型转换
{
int a = 0;
char b = 2;
int* p = nullptr;
char* cp = nullptr;
void* vp = nullptr;
std::cout << "\n####1、普通类型转换测试####\n";
//1、char -> int
a = static_cast<int>(b); //ok
//a = dynamic_cast(b); //error,类型必须是指向完整类类型或 void * 的指针或引用
//a = reinterpret_cast(b); //error,不能转换普通类型
//2、int -> int*
//p = static_cast(a); //error,无效类型转换
//p = dynamic_cast(a); //error,类型必须是指向完整类类型或 void * 的指针或引用
p = reinterpret_cast<int*>(a); //ok
//3、int* -> int
//a = static_cast(p); //error,无效类型转换
//a = dynamic_cast(p); //error,类型必须是指向完整类类型或 void * 的指针或引用
a = reinterpret_cast<int>(p); //ok
//4、char* -> int*
//p = static_cast(cp); //error,无效类型转换
//p = dynamic_cast(cp); //error,类型必须是指向完整类类型或 void * 的指针或引用
p = reinterpret_cast<int*>(cp); //ok
//5、void* -> int*
p = static_cast<int*>(vp); //ok
//p = dynamic_cast(vp); //error,类型必须是指向完整类类型或 void * 的指针或引用
p = reinterpret_cast<int*>(vp); //ok
//6、int* -> void*
vp = static_cast<void*>(p); //ok
//vp = dynamic_cast(p); //error,操作数(object)必须是指向完整类类型的指针
vp = reinterpret_cast<void*>(p); //ok
}
只能用static_cast,但无法进行下行转换
void testClass(void) //类转换
{
A a;
B b;
Father f;
Son s;
std::cout << "\n####2、类的转换测试####\n";
//1、上行转换
std::cout << "上行转换:";
f = static_cast<Father>(s); //ok
f.fun();
//f = dynamic_cast(s); //error,类型必须是指向完整类类型或 void * 的指针或引用
//f = reinterpret_cast(s); //error
//2、下行转换
//s = static_cast(f); //error,不存在转换规则
//s = dynamic_cast(f); //error,类型必须是指向完整类类型或 void * 的指针或引用
//s = reinterpret_cast(f); //error,不允许
//3、不相关类型转换
std::cout << "不相关类转换:";
a = static_cast<A>(a); //ok
a.fun();
//a = dynamic_cast(a); //error,类型必须是指向完整类类型或 void * 的指针或引用
//a = reinterpret_cast(a); //error,不允许
}
reinterpret_cast可以任意转换
static_cast和dynamic_cast只能转换具有父子关系的类型指针
其中dynamic_cast进行下行转换时必须包含多态(虚函数)
void testClassPointer(void) //类的指针转换
{
A* a = new A; //A和B是两个毫无关联的类
B* b = new B;
Father* f = new Father; //父类
Son* s = new Son; //子类
std::cout << "\n####3、类的指针转换测试####\n";
//1、上行指针转换
std::cout << "上行转换:\n";
Father* f1 = static_cast<Father*>(s); //Son -> Father
Father* f2 = dynamic_cast<Father*>(s);
Father* f3 = reinterpret_cast<Father*>(s);
f1->fun(); //都能通过
f2->fun();
f3->fun();
//2、下行指针转换
std::cout << "下行转换:\n";
Son* s1 = static_cast<Son*>(f); //可以不包含多态
Son* s2 = dynamic_cast<Son*>(f); //下行转换必须包含多态,否则编译报错
Son* s3 = reinterpret_cast<Son*>(f); //Father -> Son
s1->fun(); //包含多态时都能通过
s2->fun();
s3->fun();
//3、不相关的类型转换
std::cout << "不相关类转换:\n";
//A* a1 = static_cast(b); //error,无效类型转换
//A* a2 = dynamic_cast(b); //error,必须包含多态
A* a3 = reinterpret_cast<A*>(b); //完全强制类型转换,可转换两个毫无关系的类
a3->fun();
}
都可以转换,但dynamic_cast进行下行转换时会抛出异常
void testClassReference(void) //引用类型转换
{
A a;
A& ra = a; //A的引用
B b;
B& rb = b; //B的引用
Father f;
Father& rf = f; //Father的引用
Son s;
Son& rs = s; //Son的引用
std::cout << "\n####4、类的引用转换测试####\n";
//1、上行转换
std::cout << "上行转换\n";
rf = static_cast<Father&>(rs); //ok
rf.fun();
rf = dynamic_cast<Father&>(rs); //ok
rf.fun();
rf = reinterpret_cast<Father&>(rs); //ok
rf.fun();
//2、下行转换
std::cout << "下行转换\n";
rs = static_cast<Son&>(rf); //ok
rs.fun();
rs = dynamic_cast<Son&>(rf); //ok,会抛出异常,但能转换成功!!!
rs.fun();
rs = reinterpret_cast<Son&>(rf); //ok
rs.fun();
//3、不相关类型转换
std::cout << "不相关类转换\n";
ra = static_cast<A&>(ra); //ok
ra.fun();
ra = dynamic_cast<A&>(ra); //ok
ra.fun();
ra = reinterpret_cast<A&>(ra); //ok
ra.fun();
}
test.h
#ifndef __TEST_H
#define __TEST_H
#include
#include
//#define NO_VIRTUAL
using namespace std;
class A
{
public:
void fun()
{
std::cout << "fun A" << "\n";
}
};
class B
{
public:
void fun()
{
std::cout << "fun B" << "\n";
}
};
class Father //父类
{
public:
void fun()
{
std::cout << "fun Father\n";
}
#ifndef NO_VIRTUAL
virtual void test()
{
std::cout << "Father virtual test\n";
}
#endif
};
class Son : public Father //子类
{
public:
void fun()
{
std::cout << "fun Son\n";
}
#ifndef NO_VIRTUAL
void test() override //重写父类方法
{
std::cout << "Son virtual test\n";
}
#endif
};
#endif
test.cpp
#include "test.h"
void testGeneralType(void) //普通类型转换
{
int a = 0;
char b = 2;
int* p = nullptr;
char* cp = nullptr;
void* vp = nullptr;
std::cout << "\n####1、普通类型转换测试####\n";
//1、char -> int
a = static_cast<int>(b); //ok
//a = dynamic_cast(b); //error,类型必须是指向完整类类型或 void * 的指针或引用
//a = reinterpret_cast(b); //error,不能转换普通类型
//2、int -> int*
//p = static_cast(a); //error,无效类型转换
//p = dynamic_cast(a); //error,类型必须是指向完整类类型或 void * 的指针或引用
p = reinterpret_cast<int*>(a); //ok
//3、int* -> int
//a = static_cast(p); //error,无效类型转换
//a = dynamic_cast(p); //error,类型必须是指向完整类类型或 void * 的指针或引用
a = reinterpret_cast<int>(p); //ok
//4、char* -> int*
//p = static_cast(cp); //error,无效类型转换
//p = dynamic_cast(cp); //error,类型必须是指向完整类类型或 void * 的指针或引用
p = reinterpret_cast<int*>(cp); //ok
//5、void* -> int*
p = static_cast<int*>(vp); //ok
//p = dynamic_cast(vp); //error,类型必须是指向完整类类型或 void * 的指针或引用
p = reinterpret_cast<int*>(vp); //ok
//6、int* -> void*
vp = static_cast<void*>(p); //ok
//vp = dynamic_cast(p); //error,操作数(object)必须是指向完整类类型的指针
vp = reinterpret_cast<void*>(p); //ok
}
void testClass(void) //类转换
{
A a;
B b;
Father f;
Son s;
std::cout << "\n####2、类的转换测试####\n";
//1、上行转换
std::cout << "上行转换:";
f = static_cast<Father>(s); //ok
f.fun();
//f = dynamic_cast(s); //error,类型必须是指向完整类类型或 void * 的指针或引用
//f = reinterpret_cast(s); //error
//2、下行转换
//s = static_cast(f); //error,不存在转换规则
//s = dynamic_cast(f); //error,类型必须是指向完整类类型或 void * 的指针或引用
//s = reinterpret_cast(f); //error,不允许
//3、不相关类型转换
std::cout << "不相关类转换:";
a = static_cast<A>(a); //ok
a.fun();
//a = dynamic_cast(a); //error,类型必须是指向完整类类型或 void * 的指针或引用
//a = reinterpret_cast(a); //error,不允许
}
void testClassPointer(void) //类的指针转换
{
A* a = new A; //A和B是两个毫无关联的类
B* b = new B;
Father* f = new Father; //父类
Son* s = new Son; //子类
std::cout << "\n####3、类的指针转换测试####\n";
//1、上行指针转换
std::cout << "上行转换:\n";
Father* f1 = static_cast<Father*>(s); //Son -> Father
Father* f2 = dynamic_cast<Father*>(s);
Father* f3 = reinterpret_cast<Father*>(s);
f1->fun(); //都能通过
f2->fun();
f3->fun();
//2、下行指针转换
std::cout << "下行转换:\n";
Son* s1 = static_cast<Son*>(f); //可以不包含多态
Son* s2 = dynamic_cast<Son*>(f); //下行转换必须包含多态,否则编译报错
Son* s3 = reinterpret_cast<Son*>(f); //Father -> Son
s1->fun(); //包含多态时都能通过
s2->fun();
s3->fun();
//3、不相关的类型转换
std::cout << "不相关类转换:\n";
//A* a1 = static_cast(b); //error,无效类型转换
//A* a2 = dynamic_cast(b); //error,必须包含多态
A* a3 = reinterpret_cast<A*>(b); //完全强制类型转换,可转换两个毫无关系的类
a3->fun();
}
void testClassReference(void) //引用类型转换
{
A a;
A& ra = a; //A的引用
B b;
B& rb = b; //B的引用
Father f;
Father& rf = f; //Father的引用
Son s;
Son& rs = s; //Son的引用
std::cout << "\n####4、类的引用转换测试####\n";
//1、上行转换
std::cout << "上行转换\n";
rf = static_cast<Father&>(rs); //ok
rf.fun();
rf = dynamic_cast<Father&>(rs); //ok
rf.fun();
rf = reinterpret_cast<Father&>(rs); //ok
rf.fun();
//2、下行转换
std::cout << "下行转换\n";
rs = static_cast<Son&>(rf); //ok
rs.fun();
rs = dynamic_cast<Son&>(rf); //ok,会抛出异常,但能转换成功!!!
rs.fun();
rs = reinterpret_cast<Son&>(rf); //ok
rs.fun();
//3、不相关类型转换
std::cout << "不相关类转换\n";
ra = static_cast<A&>(ra); //ok
ra.fun();
ra = dynamic_cast<A&>(ra); //ok
ra.fun();
ra = reinterpret_cast<A&>(ra); //ok
ra.fun();
}
int main()
{
//C++强制类型转换对比测试
//运行环境 VS2019
testGeneralType(); //通用类型转换测试
testClass(); //类转换测试
testClassPointer(); //类指针转换测试
testClassReference(); //类的引用转换测试
/* 总结:
* 1、普通类型转换
* 指针和整数之间转换、指针之间转换(void*除外)只能用reinterpret_cast
* 整数之间转换可以只能用static_cast
* 2、类之间转换
* 只能用static_cast,但无法进行下行转换
* 3、类的指针转换
* reinterpret_cast可以任意转换
* static_cast和dynamic_cast只能转换具有父子关系的类型指针
* 其中dynamic_cast进行下行转换时必须包含多态(虚函数)
* 4、类的引用转换
* 都可以任意转换
*/
/* 特性
* 1、static_cast(object)
* 相当于传统的C语言里的强制转换,能转换非指针类型类和变量
* 2、dynamic_cast(object)
* 只能转换具有父子关系的类指针,而且下行转换还不许包含多态(虚函数)
* 条件比较苛刻,执行效率不高
* 3、reinterpret_cast(object)
* 强制转换一切类型指针,无任何检查,正确性由程序员自己负责
*/
return 0;
}