答案 0 :(得分:4)
在这种情况下,const_cast
将与C演员具有完全相同的效果。两者都会给出一个常量对象的非常量指针,在这两种情况下,尝试修改对象都会给出未定义的行为。
可以使用C ++强制转换的某些组合进行任何转换,但在某些情况下,C强制转换可以进行无法单个 C ++强制转换的转换。例如,reinterpret_cast
无法删除const
或volatile
条件,const_cast
无法在两个不相关的指针类型之间进行转换;但是C演员可以同时做两件事:
class A;
class B;
A const* a = 0;
B* b;
b = reinterpret_cast<B*>(a); // fail: can't remove const
b = const_cast<B*>(a); // fail: can't convert between pointer types
b = reinterpret_cast<B*>(const_cast<A*>(a)); // OK
b = (B*)a; // OK
我仍然希望在这种情况下看到两个演员阵容,但需要额外打字;它清楚地表明,一些怪异的东西正在下降,并使用可以搜索的语法。在我看来,C演员不应该用于任何事情。
答案 1 :(得分:2)
在C ++中,旧式演员表是根据新式演员表定义的。
5.4:
4未提及的任何类型转换 下面没有明确定义 用户(12.3)格式不正确。
5执行的转换 - const_cast(5.2.11), - static_cast(5.2.9), - 一个static_cast后跟一个 const_cast, - 一个reinterpret_cast (5.2.10),或 - reinterpret_cast 接下来是const_cast,可以 使用演员表示法执行 显式类型转换。
您提供的示例由第一颗子弹完全覆盖。您在示例末尾的评论只有一半是正确的。您可以读取结果,但不能写。无论您是否使用const_cast
,都是一样的。
稍后会列出一些条款,其中列出了C风格演员表与普通static_cast
不同的几种情况。但是它们与基类无法访问的继承进行转换有关。您的示例中的virtual
表明该书的实际代码中可能存在一些继承;也许那就是他想要的,你误解了?
为了完整性:
7除了那些转换之外,还有 跟随static_cast和 reinterpret_cast操作 (可选地后跟一个const_cast 操作)可以使用 显式类型的强制表示法 转换,即使是基类 类型无法访问:
- 指向 派生类类型的对象或 派生类类型的左值可能是 显式转换为指针或 引用一个明确的基类 类型,分别;
- 指向 派生类类型的成员可能是 显式转换为指向 一个明确的非虚拟成员 基类型;
- 指向的指针 非虚基类的对象, 一个非虚拟基类的左值 类型或指向非虚基类类型成员的指针可以显式转换为指针,引用或a 指向派生类类型成员的指针。
作为最后一个句子所讨论的内容的一个例子,这里只有C风格的演员才有可能。
class Base { };
class Derived : Base { };
Derived d;
Base* pb;
pb = static_cast<Base*>(&d); //inaccessible base
pb = (Base*)(&d); //just fine
然而,我发现很难想象这不会是一个坏主意的情况。出于实际目的,只假设C样式的强制转换不存在。
答案 2 :(得分:1)
最接近的候选者是const_cast,但因为a2是一个const对象,所以使用指针的结果是未定义的。
为了清楚起见,C风格的演员(A*)&a2
也会产生未定义的行为。因此const_cast
不是“最接近的候选人”,而是等效。
答案 3 :(得分:0)
似乎证明一切都是边缘情况。我从未在现实世界中遇到过这种情况。
顺便问一下,你有问题吗?