reinterpret_cast, static_cast , dynamic_cast ,const_cast 的总结

reinterpret_cast

类型修改,但仅仅是重新解释给出的对像的比特模型,不进行二进制转换。

这是为了映射到一个完全不同类型


static_cast

类型转换,用于代替C语言中的通常的转换操作。(即显示类型转换)

例如:

int i;
float f = 1.23
i = static_cast<int> (f);

 此时i的结果为1

主要用于::
1、基类和派生类之羊的指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
2、用于基本数据类型之间的转换,如 int 转 char , int 转 enum 等,这种需要自己保证安全性。
3、空指针转换成基他类型指针之间相互转换。

static_cast和reinterpret_cast的区别主要在于多重继承,比如

class A {
    public:
    int m_a;
};
 
class B {
    public:
    int m_b;
};
 
class C : public A, public B {};

 那么对于以下代码:

C c;
printf("%p, %p, %p", &c, reinterpret_cast<B*>(&c), static_cast <B*>(&c));

  

前两个的输出值是相同的,最后一个则会在原基础上偏移4个字节。

这是因为static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址(c里面有m_a,m_b,转换为B*指针后指到m_b处),而reinterpret_cast却不会做这一层转换。


dynamic_cast
将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理。(安全的)

一般用于判定是否就是目标类型的对像,如果不是,将得到NULL


const_cast

该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
1、常量指针被转化成非常量的指针,并且仍然指向原来的对象;
2、常量引用被转换成非常量的引用,并且仍然指向原来的对象;
3、const_cast一般用于修改底指针。如const char *p形式。

volatile和const类似。举如下一例:

class B
{
public:
    B() { }
public:
    int m_iNum;
};
void foo()
{
    const B b1;
    //b1.m_iNum = 100; //compile error
    // 可以做如下转换,体现出转换为指针类型
    B *b2 = const_cast<B*>(&b1);
    // 或者左侧也可以用引用类型,如果对b2或b3的数据成员做改变,就是对b1的值在做改变
    B &b3 = const_cast<B&>(b1);
    b2->m_iNum = 200;    //fine
    b3.m_iNum = 300;    //fine
}
int main( int argc, char * argv[] )
{
    foo();
    return 0;
}

  

上面代码可运行,不会报错,错误代码已经注释 。去掉下面代码行的注释号后会报错,因为b1之不可修改。
//b1.m_iNum = 100; //compile error
使用const_cast可以返回一个指向非常量的指针(或引用)指向b1,就可以通过该指针(或引用)对它的数据成员任意改变。

Stay hungry, stay foolish!
原文地址:https://www.cnblogs.com/JhonKing/p/5600816.html