在基类'复制构造函数上调用虚方法时,多态性不会被踢入

时间:2015-05-06 21:19:41

标签: c++ inheritance polymorphism

我有以下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吗?

3 个答案:

答案 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找到答案。虚拟构造函数不可用,并且您的代码就是这样。因此,从构造函数中调用虚函数将无法以您认为的方式工作。

相关问题