static_cast
概述:用于静态转换。
特点:
- 不能用于无关类型的转换,有风险,可能得到一些无意义的值,如int 转double。void 指针和具体类型指针之间的转换有极大风险。
- 编译期转换。
- 类的向下转换需要程序员保证安全性。
#include <iostream>
int main() {
int m = 100;
long n = static_cast<long>(m);
std::cout << n;
}
const_cast
概述:const_cast 就是用来将 const/volatile 类型转换为非 const/volatile 类型。
特点:
- 指针转换仍然指向原来的对象。
#include <iostream>
int main() {
const int n = 100;
int *p = const_cast<int *>(&n);
*p = 234;
std::cout << "n= " << n << std::endl;
std::cout << "*p =" << *p << std::endl;
return 0;
}
dynamic_cast
概述:dynamic_cast 用于在类的继承层次之间进行类型转换,动态转换。
特点:
- 向上转型是无条件的,不会进行任何运行期检测,所以都能成功。
- 向下转型的前提必须是安全的,要借助 RTTI 进行检测,所有只有一部分能成功。
- dynamic_cast 会在程序运行期间借助 RTTI 进行类型转换,这就要求基类必须包含虚函数。
- dynamic_case需要一定的条件:
class Base {
};
class Derived : public Base {
};
int main(){
Base *d1 = new Derived();
// auto c1 = dynamic_cast<Derived *>(d1);
// 编译不通过,因为Base不是多态的。
return 0;
}
- 基类必须是多态的,必须有虚函数。
class Base {
public:
virtual void func() {
cout << "class Base" << endl;
}
};
class Derived : public Base {
public:
void func() override {
cout << "class Derived" << endl;
}
};
int main(){
Base *d1 = new Base();
auto ctest = dynamic_cast<Derived *>(d1);
// ctest->func();
// 转换失败,运行出错,ctest是nullptr,本质上只允许向上转型。
}
- dynamic_cast本质上只允许向上转型。
class Base {
public:
virtual void func() {
cout << "class Base" << endl;
}
};
class Derived : public Base {
public:
void func() override {
cout << "class Derived" << endl;
}
};
int main(){
Derived *d1 = new Derived();
auto ctest = dynamic_cast<Base *>(d1);
ctest->func(); // 输出class Derived,成功转换
}
- 同时满足实质的向上转型和多态特性。