我假设 C 风格的转换(不鼓励)只是 reinterpret_casts 是对的吗?使用后者在寻找令人讨厌的转换时在视觉上引人注目并且易于搜索,因此推荐使用 C 风格转换?
如果使用 const_cast 放弃 const 并写入原始 const 对象是未定义的,那么 const_cast 的目的是什么?
注意:我知道 Bjarne 正确地谴责转换操作是不安全的,甚至达到了声明“丑陋 操作应该具有丑陋语法形式的程度。 “因此 C++ 中转换运算符的冗长。所以我会尽量减少它们的使用。 promise 。 :)
最佳答案
没有。 C 转换可以执行与 const_cast
、static_cast
、reinterpret_cast
或其组合等效的操作。如果这还不够,它还可以做至少一个小技巧,没有较新的类型转换组合根本做不到!
如果原始变量的定义没有const
,您可以使用const_cast
定义结果,但您所拥有的只是一个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;
}
使用reinterpret_cast
的代码将编译——但尝试使用结果(至少两者之一)将导致严重问题。 reinterpret_cast
获取派生对象的 base 地址并尝试将其视为指定类型的基对象——并且因为(至多)一个基对象实际上可以存在于该地址,试图将其视为另一个地址可能/将导致重大问题。编辑:在这种情况下,除了它们打印的内容外,这些类基本上是相同的,因此尽管可能发生任何事情,但对于大多数编译器来说,最后两个都将打印出“base 1”。 reinterpret_cast 获取该地址处的任何内容,并尝试将其用作指定类型。在这种情况下,我(试图)让它做一些无害但可见的事情。在实际代码中,结果可能不会那么漂亮。
如果代码使用公共(public)继承而不是私有(private)继承,C 风格的转换将像 static_cast 一样工作——即它知道派生类中每个基类对象“存在”的位置,并调整结果,因此每个结果指针将起作用,因为它已被调整为指向正确的位置。
关于c++ - 需要澄清 C 风格、重新解释和 const 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2346616/