【发布时间】:2016-07-03 23:59:14
【问题描述】:
我正在学习 C++ 继承,所以我通过动态创建 Base 类并对其 Derived 类进行向下转换(显然它对向下转换无效)来尝试此代码,以便使这个动态创建的 Base 对象被指向派生类指针。但是当我通过这个 Derived 指针调用方法 who() 时,它会调用 Derived 类方法而不是 Base 类方法。
根据我的假设没有为Derived类创建对象,那么怎么可能调用未创建的Derived类对象的方法而不是实际创建的Base类对象呢?
我在谷歌上搜索了这个现象,但找不到一个清晰明了的解释来调用非创建的派生类对象的方法。如果它符合标准,那么请向我解释它是如何工作的。
我知道如果我使用virtual 的方法,情况会有所不同,但这里使用的方法不是virtual。
class parent{
public:
void who(){
cout << "I am parent";
}
};
class child : public parent{
public:
void who(){
cout << "I am child";
}
};
int main(){
child *c = (child *)new parent();
c->who();
return 0;
}
输出是I am child,但我期望I am parent
编辑:: 我没有在上面的代码中释放内存并做出无效的向下转换,因为我只是想看看会发生什么。所以只解释这种调用方法的行为。
【问题讨论】:
-
行为未定义。任何事情都有可能发生。即使您将函数设为虚拟,这也是相同的未定义故事。
-
@P45Imminent - 行为未定义。您可以对观察到的行为提出合理的解释这一事实并不会改变这一点。 “未定义的行为”意味着语言定义没有告诉你发生了什么;仅此而已。
-
@jblixr 您无法通过观察行为来证明未定义行为的缺失。 “它似乎符合我的预期”是未定义行为的一个例子。它可能在不同的机器上执行其他操作,或者编译方式不同,或者在黄昏时潮低且附近有一只黑乌鸦叫。
-
您可能会从stackoverflow.com/a/3826144/5987 获得一些见解。这根本不是同一个问题,但有类似的机制。
-
§9.3.1/2 非静态成员函数 / 2. 如果为非 X 类型或非类型的对象调用类 X 的非静态成员函数从 X 派生,行为未定义。
标签: c++ pointers inheritance subclass