需要澄清C风格,重新解释和const转换

leg*_*s2k 6 c++ casting const-cast reinterpret-cast

我是否正确地假设C风格的演员阵容(不鼓励)只不过是reinterpret_casts?使用后者在寻找令人讨厌的演员阵容时视觉上引人注目且易于搜索,因此推荐使用C风格的演员阵容?

如果使用const_cast抛弃const并且未定义写入原始const对象,const_cast的目的是什么?

注意:我知道Bjarne正确地谴责他们不安全的演员操作,甚至说" 丑陋的操作应该有一个丑陋的句法形式".因此C++中的转换操作符的冗长程度.所以我会尽量减少他们的使用量.诺言.:)

Jer*_*fin 5

否。AC强制转换可以等效于a const_cast,a static_cast,a reinterpret_cast或其组合。如果这还不够的话,它还可以至少做一个小技巧,使任何新的演员阵容都无法做到!

const_cast如果原始变量未定义const,则可以使用已定义的结果,但是您所拥有的只是const该对象的指针或引用。OTOH,如果您认为有充分的理由使用const_cast,则很可能应该改mutable而抬头。

编辑:我想我应该马上说出来,但是C风格的转换可以转换为不可访问的基类。例如,考虑如下内容:

[编辑:我将代码更新为可以编译并(通常)演示问题的代码。]

#include <iostream>

class base1 {
public:
    virtual void print() { std::cout << "base 1\n"; }
};

class base2 {
public:
   virtual void print() { std::cout << "base 2\n"; }
};

class derived : base1, base2 {}; // note: private inheritance

int main() {    
    derived *d = new derived;
    base1 *b1 = (base1 *)d;    // allowed
    b1->print();    // prints "base 1"
    base2 *b2 = (base2 *)d;    // also allowed
    b2->print();    // prints "base 2"

//    base1 *bb1 = static_cast<base *>(d);  // not allowed: base is inaccessible

    // Using `reinterpret_cast` allows the code to compile.
    // Unfortunately the result is different, and normally won't work. 
    base1 *bb2 = reinterpret_cast<base1 *>(d);
    bb2->print();   // may cause nasal demons.

    base2 *bb3 = reinterpret_cast<base2 *>(d); 
    bb3->print();   // likewise
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用reinterpret_casts 的代码将进行编译-但是尝试使用结果(至少是两者之一)将导致严重问题。的reinterpret_cast的派生对象和尝试的地址来对待它,如果它是为指定的类型的基础对象的-并且由于(至多)一个基础对象实际上可以在该地址存在,试图把它当作其他的可以/将导致重大问题。编辑:在这种情况下,这些类除打印内容外基本相同,因此尽管可以碰巧,对于大多数编译器而言,后两个都将打印出“ base 1”。reinterpret_cast将获取该地址处的所有内容,并尝试将其用作指定的类型。在这种情况下,我(试图)使该操作无害但可见。在实际代码中,结果可能不会那么漂亮。

如果代码使用公共继承而不是私有继承,则C样式的强制转换将像static_cast一样工作-即,它知道每个基类对象在“派生类”中的“位置”并调整结果,因此每个结果指针将之所以有效,是因为它已被调整为指向正确的位置。

  • C样式转换可以执行的这个小技巧是什么? (3认同)