本文已参与「新人创作礼活动」,一起开启掘金创作之路。
一、今日课题
二、实战演练
C++的四种强制类型转换为:static_cast、const_cast、reinterpret_cast和dynamic_cast
类型转换的一般形式:cast-name(expression);
1)有何用?
-
dynamic_cast 主要用于执行“安全的向下转型(safe downcasting)”,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。它是唯一不能用旧风格语法执行的强制转型,也是唯一可能有重大运行时代价的强制转型。
-
static_cast 可以被用于强制隐型转换(例如,non-const 对象转型为 const 对象,int 转型为 double,等等),它还可以用于很多这样的转换的反向转换(例如,void* 指针转型为有类型指针,基类指针转型为派生类指针),但是它不能将一个 const 对象转型为 non-const 对象(只有 const_cast 能做到),它最接近于C-style的转换
-
const_cast 一般用于强制消除对象的常量性。它是唯一能做到这一点的 C++ 风格的强制转型。
-
reinterpret_cast 是特意用于底层的强制转型,导致实现依赖(implementation-dependent)(就是说,不可移植)的结果,例如,将一个指针转型为一个整数。这样的强制转型在底层代码以外应该极为罕见。
2)怎么用?
- static_cast: 编译器在编译期处理, 将地址a转换成类型T,T和a必须是指针、引用、算术类型或枚举类型
class A{ ... };
class B{ ... };
class D : public B{ ... };
void f(B *pb, D *pd)
{
D *pd2 = static_cast<D*>(pb); //不安全,pb可能只是B的指针
B *pd2 = static_cast<B*>(pb); //安全的
A*pd2 = static_cast<A*>(pb); //错误A与B没有继承关系
}
- dynamic_cast :编译器在运行期,会检查这个转换是否可能,完成类层次结构中的提升.
class Base{virtual dummy() };
class Derived : public Base{};
Base* b1 = new Derived;
Base* b2 = new Base;
Derived* d1 = dynamic_cast<Derived *>(b1); //succeed
Derived* d2 = dynamic_cast<Derived *>(b2);
- const_cast :编译器在编译期处理,去掉类型中的常量
class A{ ...};
void f()
{
const A *pa = new A; //const对象
A* pb;
pb = const_cast<A*>(pa);
}
const char* p = "123";
char* c = const_cast<char*>(p);
c[0] = 1;
- reinterpret_cast:编译器在编译期处理,任何指针都可以转换成其它类型的指针
class A{...};
class C{...};
void f()
{
A* pa = new A;
void* pv = reinterpret_cast<A*>(pa);
}