深入解析:速通C++类型转换(代码+注释)
本文包含以下内容:
1、对C语言两种主要的类型转换方式的回顾
2、C++中内置类型->自定义类型、自定义类型->内置类型、自定义类型->自定义类型的转换方式
3、C++和C语言都不是类型安全的语言
4、C++四种展示强制类型转换:static_cast, reinterpret_cast, const_cast, dynamic_cast
5、RTTI主要理解(RUNTIME TYPE IDENTIFICATION)
class A
{
public:
//explicit A(int a);
//有explicit就不再支持隐式类型转换
//如果还想使用类型转换,直接强制类型转换即可
A(int a)
: _a1(a)
, _a2(a)
{
//有构造函数可以支持内置-》自定义
}
A(int a, int b)
: _a1(a)
, _a2(b)
{
}
int get1()
{
return _a1;
}
int get2()
{
return _a2;
}
//自定义类型转换成内置类型——也是支持的隐式的类型转换
operator int() const
{
return _a1 + _a2;
}
private:
int _a1;
int _a2;
};
class B
{
public:
B(int b1, int b2)
: _b1(b1)
, _b2(b2)
{
}
B(const A& aa)//自定义类型转换成自定义类型
: _b1((int)aa)
, _b2((int)aa)
{
}
private:
int _b1;
int _b2;
};
int main()
{
//不是所有类型都支持类型转换,有意义的才支持隐式类型转换
//
char ch = 'a';
//int i = &ch;//这里就不可以
int i = (int)(&ch);//只能采取这种显示强制的方式
//double j = (double)&i;//这样的强制类型转换也不可以
//C++还支持内置类型和自定义类型的转换
//内置类型转换成自定义类型需要operator类型()
//自定义类型转换成内置类型需要构造函数
A a = 1;
A aa = (1, 1);//这是逗号表达式,多参数需要使用花括号
A aaa = { 1, 1 };//自定义类型转换为内置类型
int b = a;
cout sp1;
shared_ptr sp2(new int);
if (sp1)
{
cout ::const_iterator cit = lt.begin();
//C和C++都不是类型安全的语言,因为他们都允许类型转换
const int i1 = 0;
int* p = (int*)&i1;
volatile const int i2 = 0;
int* p2 = (int*)&i2;
(*p) = 1; (*p2) = 1;
cout (f);
cout (f);
//reinterpret_cast,用于两个意义不太相近的转换,转换后对内存的访问解释
//已经完全改变了
int* h = reinterpret_cast(e);
//cout (&l);
//dynamic_cast用于将基类的指针或引用转换成派生类的指针或者引用
//如果基类的指针或引用指向的是派生类,那么转换成功;如果基类的指针或者引用
//指向基类,则转换失败,抛出bad_cast异常;同时,dynamic_cast还要求基类
//满足多态,即内部有虚函数,因为dynamic_cast是通过虚表中指向的type_info
//来判断是基类还是派生类的(这种转换是安全的)
//RTTI运行时类型识别Runtime Type Identification
//指的是程序在运行的的时候才能确定需要用到的对象是什么类型,用于在运行时获取
//有关类型的信息,RTTI主要通过typeid和dynamic_cast实现
typedef class A alpha;
cout << typeid(alpha).name() << endl;
cout << typeid(10).name() << endl;
cout << typeid(string).name() << endl;
//typeid不完全是RTTI,dynamic_cast是完全的RTTI,
B* pbb = new B{ 1, 1 };
A* paa = (A*)pbb;
if (typeid(*pbb) == typeid(B))
{
cout << "typeid(*pbb) == typeid(B)" << endl;
}
//这里就是RTTI的体现,类似于dynamic_cast,通过虚表指针发现基类的指针或者引用指向的是派生类
/*if (typeid(*paa) == typeid(B))
{
cout << "typeid(*paa) == typeid(B)" << endl;
}假设这里A是多态,B对A进行了继承*/
if (typeid(paa) == typeid(pbb))
{
cout << "typeid(paa) == typeid(pbb)" << endl;
}//不是类类型对象,就会被当作静态对象处理,在编译时就确定
return 0;
}