向下投射基本类型 在C++中,如果基类对象实例化为基础对象,然后向下压缩为派生对象,则是未定义行为吗?

向下投射基本类型 在C++中,如果基类对象实例化为基础对象,然后向下压缩为派生对象,则是未定义行为吗?,c++,inheritance,C++,Inheritance,当然,我会假设它肯定是未定义的行为,因为派生类对象可能有基类没有的成员变量。因此,如果类被实例化为基对象,那么这些变量实际上就不存在,这意味着通过派生类指针访问它们将导致未定义的行为 但是,如果派生类只提供额外的成员函数,但不包含任何进一步的成员数据,该怎么办?例如: class Base { public: int x; }; class Derived : public Base { public: void foo(); }; int main(

当然,我会假设它肯定是未定义的行为,因为派生类对象可能有基类没有的成员变量。因此,如果类被实例化为基对象,那么这些变量实际上就不存在,这意味着通过派生类指针访问它们将导致未定义的行为

但是,如果派生类只提供额外的成员函数,但不包含任何进一步的成员数据,该怎么办?例如:

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?
}
类基
{
公众:
int x;
};
派生类:公共基
{
公众:
void foo();
};
int main()
{
碱基b;
派生*d=静态_转换(&b);

d->foo();//是的,这是完全未定义的行为。这就是为什么在降级时,除非你非常确定,否则你应该支持
dynamic\u cast

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

见标准5.2.9/8:

类型为“指向cv1 B的指针”的右值, 其中B是类类型,可以是 已转换为类型为的右值 “指向cv2 D的指针”,其中D是一个类 从B派生(第10条),如果a有效 从“指针到”的标准转换 存在指向B的指针(4.10), cv2与cv2相同,或 大于、cv1和 B不是D的虚拟基类。 空指针值(4.10)为 已转换为的空指针值 目标类型。如果 类型“指向cv1 B的指针”指向a B 这实际上是一个对象的子对象 类型为D的对象,结果为 指针指向封闭对象 D类。否则 演员阵容尚未确定


最后两个句子表示,如果指针指向的<代码> B <代码>实际上不是<代码> d>代码>派生类的一部分,则该CAST是未定义行为。

< P> C++ 03标准,PA5.5.2.9列出(强调矿):

类型为“指向cv1 B的指针”的右值, 其中B是类类型,可以是 已转换为类型为的右值 “指向cv2 D的指针”,其中D是一个类 从B派生(第10条),如果a有效 从“指针到”的标准转换 存在指向B的指针(4.10), cv2与, 或大于cv1的cv资格, B不是的虚拟基类 D.空指针值(4.10)为 已转换为的空指针值 目标类型。如果 类型“指向cv1 B的指针”指向a B 这实际上是一个对象的子对象 类型为D的对象,结果为 指针指向封闭对象 D类。否则 演员阵容未定义。


< P>在生成的机器代码中,给出了C++实现的心智模型,我会说,如果调用的方法不是虚拟的,派生类在基类没有时不引入虚拟方法,并且在这个欺骗中不涉及多重继承,并且……它应该按照您的预期,如果方法代码I它实际上只访问在基本对象中定义的成员


P>但是,在C++中,这仍然是很清楚的。

注意,在这个例子中,由于没有虚拟函数<代码> DyjiCysCase将不起作用。它可能适用于一个非常小事的情况,但是如果你有多个继承或一个以上的继承层,它不一定会起作用。e基本对象不在派生对象中的偏移量0处。我编辑了回复。