【问题标题】:Accessing base class members with incorrect downcast in C++在 C++ 中使用不正确的向下转换访问基类成员
【发布时间】:2018-02-22 14:44:38
【问题描述】:

以下 C++ 代码是否正确?

struct Base { int x; };
struct Derived : Base { int y; }
Base * b = new Base;
Derived * d = static_cast<Derived *>(b);
//below we access only d->x, but not d->y
std::cout << d->x;

如果不是,究竟是什么问题? C++ 标准对此有何评论?至少我没见过它崩溃过。

【问题讨论】:

  • xy 在这里是私有的。
  • Base b = new Base; 给你一个Base。你不能只是神奇地得到一个Derived
  • 并且仅仅因为这个简单的示例有效并不意味着您可以依赖它来处理其他情况。
  • static_cast 定义明确的规则可以在这里找到:en.cppreference.com/w/cpp/language/static_cast
  • @NathanOliver 实际上问题并不那么明显,OP 提到他只会通过d 访问Base 成员

标签: c++ language-lawyer


【解决方案1】:

这在[expr.static.cast]/11 中相当简单(强调我的):

类型为“指向 cv1 B”的纯右值,其中 B 是类类型,可以转换为类型为“指向 cv2 D”的纯右值,其中 D 是从 B 派生的类,如果 cv2 与 cv1 的 cv 限定相同或更高。如果 B 是 D 的虚拟基类或 D 的虚拟基类的基类,或者如果不存在从“指向 D 的指针”到“指向 B 的指针”的有效标准转换 ([conv.ptr]),则程序格式不正确。空指针值转换为目标类型的空指针值。 如果“指向 cv1 B 的指针”类型的纯右值指向实际上是 D 类型对象的子对象的 B,则生成的指针指向 D 类型的封闭对象。否则,行为未定义。

您没有 Derived 的子对象,因此这是未定义的行为。


请注意,左值或 xvalue 指针没有特殊情况,/8 提到操作数经历了左值到右值的转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    相关资源
    最近更新 更多