0

I have the following C++ code:

#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);
}

Class My inherits from Base. The important thing is that Base has a virtual method foo which is overridden in My.

Polymorphism not kicking in

In the copy ctor of Base, called by My's copy ctor, I call foo. However I expect Base::Base(const Base&) to call My::foo, however when running the program I get:

Base::foo

Why is this happening? Should polymorphism have My::foo be called?

Community
  • 1
  • 1
Andry
  • 16,172
  • 27
  • 138
  • 246

3 Answers3

1

Why is this happening?

This is happening because the virtual table is not fully defined at that time. The virtual functions of derived classes are not set yet when base classes being constructed. They will be set in the virtual table when the derived classes are constructed.

Should polymorphism have My::foo be called?

No. The above explanation should suffice.

Virtual functions can be reliably called only inside the body of the constructor of the most derived class:

// This should work
My(const My& other) : Base(other) { this->foo(); }
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

Dynamic dispatch is disabled during construction and destruction. This is by design. Inside a Base constructor, the My part of the object hasn't been constructed yet, so it makes no sense to call My's overrider, which might access uninitialized members of My or otherwise depend upon My's invariants that have not yet been established since My's constructor hasn't completed yet.

If this causes problems for you, you'll have to explain specifically what outcome you desire (post a new question) so workarounds can be suggested.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
0

You will find the answer in this. Virtual constructor is not available and with your code it would be that. So calling a virtual function from a constructor will not work in a way that you think.

Community
  • 1
  • 1
p.i.g.
  • 2,815
  • 2
  • 24
  • 41