我们常见的类型转化有:
1. 内置类型转化内置类型
2. 内置类型转化自定义类型
3. 自定义类型转化内置类型
4. 自定义类型转化自定义类型
本篇博客就是针对上述转化进行讲解……
一、内置类型转化内置类型
我们知道在C语言中支持浮点型向整型的隐式类型转化,也支持从地址常量向整型的转化,而C++孕育于C语言,他对这一部分也同样适配
void test1()
{
double x = 1.08;
int y = x;
cout << y << endl;
double* px = &x;
y = (int)px;
cout << y << endl;
}
二、内置类型转化自定义类型
这一部分在之前的博客中有所涉猎,例如在模拟string实现时,我们可以通过char*类型的字符串对string进行构造
void test2()
{
string str("11111111");
cout << str;
}
三、自定义类型转化内置类型
这种情况在一般状况下并不常见,例如输入输出流中的判断是否到达文件结尾,就是将其转化为了bool类型,如下:
class A
{
public:
A(int x)
{
_a = x;
}
operator int()
{
return _a;
}
private:
int _a;
};
void test3()
{
A aa(1);
int x = aa;
cout << x;
}
四、自定义类型转化自定义类型
struct B
{
B(int x):_b(x){}
int _b;
};
class A
{
public:
A(int x):_a(x){}
A(const B& b):_a(b._b){}
private:
int _a;
};
void test4()
{
B b(10);
A a(b);
}
五、C++强制类型转化
标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:static_cast、reinterpret_cast、const_cast、dynamic_cast
5.1 static_cast
即隐式类型转化
int main()
{
double d = 12.34;
int a = static_cast<int>(d);
cout<<a<<endl;
return 0;
}
5.2 reinterpret_cast
即强制类型转化
int main()
{
double d = 12.34;
int a = static_cast<int>(d);
cout << a << endl;
int *p = reinterpret_cast<int*>(a);
return 0;
}
5.3 const_cast
常用的用途就是删除变量的const属性,方便赋值
void Test ()
{
const int a = 2;
int* p = const_cast< int*>(&a );
*p = 3;
cout<<a <<endl;
}
5.4 dynamic_cast
dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)
向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
注意:
1. dynamic_cast只能用于父类含有虚函数的类
2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
class A
{
public :
virtual void f(){}
};
class B : public A
{};
void fun (A* pa)
{
// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回
B* pb1 = static_cast<B*>(pa);
B* pb2 = dynamic_cast<B*>(pa);
cout<<"pb1:" <<pb1<< endl;
cout<<"pb2:" <<pb2<< endl;
}
int main ()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}
注意
强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。强烈建议:避免使用强制类型转换
六、RTTI
RTTI:Run-time Type identification的简称,即:运行时类型识别。
C++通过以下方式来支持RTTI:
1. typeid运算符
2. dynamic_cast运算符
3. decltype