C++中可以使用C的强制类型转换但是为了更加规范C++制定了四种强转。
1. const_cast
顾名思义,把常量指针和引用强转为非常量指针和引用,强转后变量指向当初的常量对象。这个强转发生在编译的时候。设计这个函数的主要目的是解决某些情况的无奈之举。比如我用一个const引用或者const指针指向一个非const对象,但是后来我又想用这个指针或者引用去改指向的变量就会用到。
int v = 1;
const int* a = &v;
int* b = const_cast<int*>(a);
++(*b);
而用一个const引用指针或者是引用指向一个const变量然后再强转成非const再更改值这种情况就是一个UB
const int v = 1;
const int* a = &v;
int* b = const_cast<int*>(a);
++(*b); // UB
2. static_cast
这个强制类型转换有点类似于C的强制类型转换,在运行时不会对类型的downcast安全性进行检测,但是会做基本的类型检测。这个强转发生在编译的时候。也可以做基本数据类型的强转。比如从char转到int。
class A{
public:
int v1;
};
class B : public A{
public:
int v2;
int v3;
};
B* b = new B();
A* a = static_cast<A*>(b);
// char* c = static_cast<A*>(b); error
//A* a = new A();
//B* b = static_cast<B*>(a); // wrong but can run
3. dynamic_cast
这个强制类型转换与static_cast不同的是会在downcast的时候做安全检测,如果强转失败则会返回对应类型的空指针。由于需要安全监测,所以这个强转发生在运行时,关于runtime的安全检测机制,C++使用了RTTI(runtime type information)来获得相关信息。
#include <iostream>
struct V {
virtual void f() {}; // must be polymorphic to use runtime-checked dynamic_cast
};
struct A : virtual V {};
struct B : virtual V {
B(V* v, A* a) {
// casts during construction (see the call in the constructor of D below)
dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B, results in B*
dynamic_cast<B*>(a); // undefined behavior: a has type A*, A not a base of B
}
};
struct D : A, B {
D() : B(static_cast<A*>(this), this) { }
};
struct Base {
virtual ~Base() {}
};
struct Derived: Base {
virtual void name() {}
};
int main()
{
D d; // the most derived object
A& a = d; // upcast, dynamic_cast may be used, but unnecessary
D& new_d = dynamic_cast<D&>(a); // downcast
B& new_b = dynamic_cast<B&>(a); // sidecast
Base* b1 = new Base;
if(Derived* d = dynamic_cast<Derived*>(b1))
{
std::cout << "downcast from b1 to d successful\n";
d->name(); // safe to call
}
Base* b2 = new Derived;
if(Derived* d = dynamic_cast<Derived*>(b2))
{
std::cout << "downcast from b2 to d successful\n";
d->name(); // safe to call
}
delete b1;
delete b2;
}
4. reinterprent_cast
这个强制类型转换不做任何的检查,程序员说啥就是啥,这个强转也发生在编译时期。就像名字一样对变量进行重新解释,因此比较危险,使用的时候需要小心。