Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Virtual inheritance constructor selection

Why does this print 20000? Code explicitly calls specific base constructors all the way up the inheritance train, yet ignores specified constructor and uses the default constructor instead.

#include <iostream>

struct Car
{
  Car() : price(20000) {}
  Car(double b) : price(b*1.1) {}
  double price;
};

struct Toyota : public virtual Car
{
  Toyota(double b) : Car(b) {}
};

struct Prius : public Toyota
{
  Prius(double b) : Toyota(b)  {}
};

int main(int argc, char** argv)
{
  Prius p(30000);

  std::cout << p.price << std::endl;

  return 0;
}
like image 272
code Avatar asked Apr 26 '18 18:04

code


People also ask

What happens to constructor in inheritance?

Constructor is automatically called when the object is created. Multiple Inheritance: Multiple Inheritance is a feature of C++ where a class can derive from several(two or more) base classes. The constructors of inherited classes are called in the same order in which they are inherited.

Why Virtual constructors are not allowed?

In C++, constructor cannot be virtual, because when constructor of a class is executed there is no virtual table in the memory, means no virtual pointer defined yet. So, the constructor should always be non-virtual.

Can we use virtual function in constructor?

You can call a virtual function in a constructor, but be careful. It may not do what you expect. In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn't yet happened. Objects are constructed from the base up, “base before derived”.

Does inheritance inherit constructors?

Constructors are not inherited. The superclass constructor can be called from the first line of a subclass constructor by using the keyword super and passing appropriate parameters to set the private instance variables of the superclass.


1 Answers

Virtual base class must be constructed by the most-derived class; that's the only way that makes sense considering the possibility of a diamond-shaped hierarchy.

In your case, Prius constructs Car using its default constructor. If you want the other constructor, you'd have to call it explicitly, as in

Prius(double b) : Car(b), Toyota(b) {}
like image 160
Igor Tandetnik Avatar answered Oct 15 '22 04:10

Igor Tandetnik