我有以下C ++代码:
#include <iostream>
class Base {
public:
Base() { }
Base(const Base& other) { this->foo(); }
virtual ~Base() { }
virtual void foo() { std::cout << "Base::foo" << std::endl; }
};
class My : public Base {
public:
My() : Base() { }
My(const My& other) : Base(other) { }
virtual ~My() { }
void foo() { std::cout << "My::foo" << std::endl; }
};
int main(int argc, char** argv);
int main(int argc, char** argv) {
My* my = new My();
My* my2 = new My(*my);
}
班级My
继承自Base
。重要的是Base
有一个虚拟方法foo
,它在My
中被覆盖。
在由Base
的副本ctor调用的My
副本中,我致电foo
。但是我希望Base::Base(const Base&)
可以调用My::foo
,但是在运行程序时,我会得到:
基地:: foo的
为什么会这样?多态性应该被调用My::foo
吗?
答案 0 :(得分:1)
为什么会这样?
这种情况正在发生,因为此时虚拟表尚未完全定义。当构造基类时,尚未设置派生类的虚函数。在构造派生类时,它们将在虚拟表中设置。
多态性是否应该调用My :: foo?
没有。上面的解释就足够了。
只能在派生程度最高的类的构造函数体内可靠地调用虚函数:
// This should work
My(const My& other) : Base(other) { this->foo(); }
答案 1 :(得分:1)
在构建和销毁期间禁用动态分派。这是设计的。在Base
构造函数中,对象的My
部分尚未构造,因此调用My
的覆盖是没有意义的,这可能会访问My
的未初始化成员1}}或以其他方式依赖于My
的构造函数尚未完成之前尚未建立的不变量。
如果这会给您带来问题,您必须具体说明您想要的结果(发布新问题),以便建议解决方法。
答案 2 :(得分:0)
您可以在this找到答案。虚拟构造函数不可用,并且您的代码就是这样。因此,从构造函数中调用虚函数将无法以您认为的方式工作。