1

I am working on a C++ project wherein I am making use of multi-level inheritance.

This is my sample code:

class ClassA
{
public:
    ClassA(int a,int b) : sum(a + b) {}
    virtual ~ClassA() = default;

    int sum;
};

class ClassB : virtual public ClassA
{
public:
    ClassB(int a, int b, int c) : ClassA(a, b), c(c) {}

    int c;
};

class ClassC : virtual public ClassB
{
public:
    ClassC(int a,int b,int c) : ClassB(a, b, c) {}
};

int main()
{
    ClassC objC(1, 2, 3);

    std::cout << "sum=" << objC.sum << std::endl;
    std::cout << "c=" << objC.c << std::endl;
}

Can somebody explain me what is wrong in this code.

error: no matching function for call to 'ClassA::ClassA()'
ClassC(int a,int b,int c) : ClassB(a, b, c) {}

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Harry
  • 2,177
  • 1
  • 19
  • 33
  • 4
    "I am not able to compile" - then you should post compilation log here. Compiler probably explains what is wrong. – user7860670 Oct 12 '18 at 13:38
  • What compiler error message do you have? – Dominique Oct 12 '18 at 13:43
  • 3
    All virtual bases are constructed first. Since `classC` doesn't list `classA` in its initialiser list, the compiler looks for a constructor of `classA` that accepts no arguments - because the virtual `classA` will be constructed BEFORE attempting construction of the virtual `classB`, so the construction `classB` does of `classA` doesn't happen. To resolve the compilation error, either provide `classA` with a default constructor, or invoke the constructor of `classA` in `classC`s initialiser list (in addition to, not instead of, the construction of `classB`). – Peter Oct 12 '18 at 13:48
  • @Peter Thank you. It worked – Harry Oct 12 '18 at 14:14
  • 2
    Possible duplicate of [Why must virtual base classes be constructed by the most derived class?](https://stackoverflow.com/questions/44324583/why-must-virtual-base-classes-be-constructed-by-the-most-derived-class) – 1201ProgramAlarm Oct 12 '18 at 21:06
  • @Peter A base class subobject is always constructed (both body entry and body exit) before a derived class. What virtual changes is the way ctor-init-list works (order of entry of ctor-init-list). – curiousguy Oct 15 '18 at 17:22
  • @curiousguy - You've missed the point. Yes, all bases are constructed before the derived class. However, the construction order differs for virtual bases, so virtual bases are constructed before other bases. The interaction with constructor initialiser list that you refer to is only part of that. – Peter Oct 16 '18 at 08:52
  • @Peter "_so virtual bases are constructed before other bases_" I don't see "other bases" here, so... – curiousguy Oct 16 '18 at 15:14

1 Answers1

1

From Derived class:

All virtual base subobjects are initialized before any non-virtual base subobject, so only the most derived class calls the constructors of the virtual bases in its member initializer list:

So your class should be modified to:

ClassC::ClassC(int a, int b,int c):ClassA(a, b), ClassB(a, b, c) {}
Jarod42
  • 203,559
  • 14
  • 181
  • 302