1、const_cast
他的主要作用就是去掉(指针或者引用)常量属性的类型转换。
例如,当我们想将一个常量a的指针转成一个int*,在c语言中可以用如下的方式强制转换。
int main()
{
const int a = 10;
int* p = (int*)&a;
return 0;
}
但是在c++中,我们就有了const_cast,就可以使用如下的方式转换:
int main()
{
const int a = 10;
int* p2 = const_cast<int*>(&a);
return 0;
}
可以将其看成一个模板,在模板里面提供转换成的类型
注意!!
- 上述两种转换在底层(转成汇编指令过后)实现是一模一样的
- char* p = (char*)&a;是可以的,但是char* p2 = const_cast<char*>(&a);是不可以的。因为,const_cast在提供强转的时候,需要表达式(地址类型)与左边定义的类型,包括要转换的类型应该保持一致。防止了任意转换类型导致一些不可预期的问题。
- const_cast<引用这里面必须是指针或引用类型 int int&*>
2、static_cast
他的主要作用是提供编译器认为安全的类型转换(没有任何联系的类型之间的转换就被否定了),也是我们最常用的一种转换方式。
例如,如果像下面这样写编译器就会直接报错
int *p = nullptr;
short* b = static_cast<short*>(a);
另外,基类类型 <=>派生类类型 可以用static_cast转换
3、reinterpret_cast
他的作用就类似于c风格的强制类型转换。你想要怎样转换都可。
4、dynamic_cast
他的主要作用是用在继承结构中,可以支持RTTI类型识别的上下转换
为了更好的解释他的作用,我们先实现一个继承的代码如下:
class Base
{
public:
virtual void func() = 0;
};
class Derive1 :public Base
{
public:
void func() { cout << "call Derive1::func" << endl; }
};
class Derive2 :public Base
{
public:
void func() { cout << "call Derive2::func" << endl; }
};
void showFunc(Base* p)
{
p->func();//动态绑定
}
int main()
{
Derive1 d1;
Derive2 d2;
showFunc(&d1);
showFunc(&d2);
return 0;
}
运行结果如下:
上述代码都实现的是动态绑定,最后输出自己对应的函数。
但是当我们的需求改变,当访问到Derive2对象时,要实现Derive02func()方法时应该怎么办呢?
首先,需求更改了 Derive2实现新功能的API接口函数如下:
class Derive2 :public Base
{
public:
void func() { cout << "call Derive2::func" << endl; }
void Derive02func() { cout << "call Derive02func::func" << endl; }
};
接下来就思考void showFunc(Base* p)里面如何修改了。
因为需求改变了,当访问到Derive2对象时,要实现Derive02func()方法,所以要关注*p的类型。
在我们之前所学的知识里面可以用
typeid(*p).name() == "Derive2"
来进行一个类型的比较,但是这样不好。
这时就要提出我们的dynamic_cast类型转换了。
Derive2* pd2 = dynamic_cast<Derive2*>(p);
把p类型的指针转成Derive2* 类型的指针,dynamic_cast会检查p指针是否指向的是一个Derive2类型的对象。通过p 访问vfptr进而访问对象的vftable 里面存放了RTTI信息 如果是dynamic_cast转换类型成功,返回Derive2对象的地址,给pd2,否则返回nullptr
因此,void showFunc(Base* p)里面代码实现如下:
void showFunc(Base* p)
{
Derive2* pd2 = dynamic_cast<Derive2*>(p);
if (pd2 != nullptr)
{
pd2->Derive02func();
}
else
{
p->func();//动态绑定
}
}
运行结果如下:
由此可以看出static_cast编译时期的类型转换,dynamic_cast运行时期的类型转换,支持RTTI信息识别的