向下转型基础类型

Cha*_*l72 4 c++ inheritance

在C++中,如果将基类对象实例化为基础对象,然后向下转换为派生对象,它是未定义行为吗?

当然,我认为它肯定必须是未定义的行为,因为Derived类对象可能具有基类不具有的成员变量.因此,如果将类实例化为基础对象,则这些变量实际上不存在,这意味着通过Derived类指针访问它们必须导致未定义的行为.

但是,如果Derived类只提供额外的成员函数,但不包含任何其他成员数据,该怎么办?例如:

class Base
{
    public:
    int x;
};

class Derived : public Base
{
    public:
    void foo();    
};

int main()
{
    Base b;
    Derived* d = static_cast<Derived*>(&b);
    d->foo(); // <--- Is this undefined behavior?
}
Run Code Online (Sandbox Code Playgroud)

该程序是否会导致未定义的行为?

Mar*_*k B 7

是的,它仍然是未定义的行为,因为你对编译器说谎的真实类型d.

见标准5.2.9/8:

类型为"指向cv1 B的指针"的左值,其中B是类类型,可以转换为"指向cv2 D的指针"类型的右值,其中D是来自B的派生类(第10节),如果是有效标准从"指向D的指针"到"指向B的指针"的转换存在(4.10),cv2与cv1相同,或者更高的cvqualification,而cv1和B不是D的虚基类.空指针值(4.10)转换为目标类型的空指针值.如果"指向cv1 B的指针"类型的右值指向实际上是类型D的对象的子对象的B,则结果指针指向类型D的封闭对象.否则,未定义强制转换的结果.

最后两句话说如果B指针所指向的实际上不是D派生类的一部分,那么转换是未定义的行为.