在C语言中,有隐式类型的转换和强制类型的转换.
隐式类型的转换:相关类型的转换,即意义相似的类型.
强制类型的转换:不类型类型的转换,比如:指针和整型.
例如:
int i = 20;
double d = i;
int* p = (int*)i;
以下是C++的类型转换的四种类型.它们都是类模板.
static_case(静态转换)
不可以用于多态类型的转换.
不可以用于静态类型的转换.
例如:
7 int i = 3;
8 double b1 = static_cast<double>(i);
9 cout<<b1<<endl;
但是不相关类型是不可以转换的,比如下面:
int* p = static_cast<int*>(i);
整形和指针属于两种完全不同的类型,所以是不可以通过static_cast转换.
reinterpret_cast(不相关类型的转换)
reinterpret的英文含义有重新转换的含义.
就相当于C语言中不相关类型的转换,强转.
在上面的例子中,不相关类型使用static_cast是不可以转换的.
例如:
int* p = static_cast<int*>(i);
但是可以通过reinterpret_cast来进行转换.
例如:
int* p = reinterpret_cast<int*>(i);
不仅仅只有变量类型可以转换,函数也可以:
6 typedef void(*Fun)();
7 int Test(int i)
8 {
9 cout<<"Test"<<endl<<i<<endl;
10 return 0;
11 }
12 void fun()
13 {
14 Fun f = reinterpret_cast<Fun>(Test);
15 f();
16 }
但是不建议使用reinterpert_cast来进行函数指针的强转,完全可以用C语言的强转来实现.
const_cast
19 const int i = 10;
20 int* p = const_cast<int*>(&i);
21 *p = 20;
22 cout<<i<<endl;
23 cout<<*p<<endl;
运行结果:
解决:加volatile
19 volatile const int i = 10;
20 int* p = const_cast<int*>(&i);
21 *p = 20;
22 cout<<i<<endl;
23 cout<<*p<<endl;
dynmic_cast(动态转换)
目的:用于讲一个父类的指针/引用转化为子类的指针/引用.在前面的学习中,我们知道,把一个子类的指针或引用转化为父类的指针/引用,这是可以很自然的转换,会发生切片的行为.
这种类型的转换在C语言中是不支持的,因为在C语言中还没有出现多态.
使用场景:
1.dynamic只能用于含有虚函数的类.
2.dynamic在进行转换时先会检查是否会转换成功,能成功则转,不成功就会返回0;
36 void fun(AA* ptr)
37 {
38 ptr->F()
39 BB* b = (BB*)ptr
40 cout<<"a:"<<b->a<<endl
41 cout<<"b:"<<b->b<<endl
42 }
59 int main()
60 {
61 AA a
62 a.a = 1
63 BB b
64 b.a = 10
65 b.b = 100
66 fun(&a)
67 fun(&b)
68 }
所以为了解决上面的问题,同时打印父类和子类的成员变量.所以此时就可以使用dynamic_cast来进行转换了.
43 void fun(AA* ptr)
44 {
45 ptr->F();
46 BB* b = dynamic_cast<BB*>(ptr);
47 if(b)
48 {
49 cout<<"转换成功"<<endl;
50 cout<<"a:"<<b->a<<endl;
51 cout<<"b:"<<b->b<<endl;
52 }
53 else
54 {
55 cout<<"转换失败"<<endl;
56 cout<<"a:"<<ptr->a<<endl;
57 }
58 }
运行结果为:
如果此时在BB类中不重写F()函数.但是父类AA()类有虚函数,有虚表.BB类继承了AA自然也会有虚表,所以在子类中不重写虚函数也可以用来转换.但是如果在父类中没有虚函数,那么就会直接编译不通过.
在C++中,支持单参数的隐式类型的转换.只能有一个成员变量
例如:
52 class CC
53 {
54 public:
55 CC(int _a)
56 :a(_a)
57 {
58 cout<<"a:"<<a<<endl;
59 }
60 private:
61 int a;
62 };
63 int main()
64 {
65 CC c(10);
66 CC c1 = 20;
67 return 0;
68 }
运行结果为:
但是如果不想发生隐式类型的转换,就可以加上关键字:explicit.
加上关键字后就可以防止被转换,直接会编译报错.
 |