Problem with virtual inheritance

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Harinezumi
    New Member
    • Feb 2008
    • 32

    Problem with virtual inheritance

    Hi,

    I have a Base class, a class VDer that virtually inherits from it, and a Final class that inherits from VDer.
    The Base class only has a constructor which has a parameter.

    class Base {
    public:
    Base(const string& par) : par(par) {}
    private:
    string par;
    };

    class VDer : public virtual Base
    {
    public:
    VDer1(const string& par) : Base(par) {}
    };

    class Final : public VDer
    {
    public:
    Final(const string& par) : VDer(par) {}
    };

    The compiler complains that "no matching function for call to 'Base::Base()'" .
    Why does the compiler want to call Base constr without parameter? How can this be solved?
    (NOTE: Base must not have a constructor without parameter).
    I know that virtual inheritance may not be the best option, but I would like to know the answer to this problem anyway.

    Thanks in advance,
    Harinezumi
  • Savage
    Recognized Expert Top Contributor
    • Feb 2007
    • 1759

    #2
    Originally posted by Harinezumi
    Hi,

    I have a Base class, a class VDer that virtually inherits from it, and a Final class that inherits from VDer.
    The Base class only has a constructor which has a parameter.

    [CODE=cpp]class Base {
    public:
    Base(const string& par) : par(par) {}
    private:
    string par;
    };

    class VDer : public virtual Base
    {
    public:
    VDer1(const string& par) : Base(par) {}
    };

    class Final : public VDer
    {
    public:
    Final(const string& par) : VDer(par) {}
    };[/CODE]

    The compiler complains that "no matching function for call to 'Base::Base()'" .
    Why does the compiler want to call Base constr without parameter? How can this be solved?
    (NOTE: Base must not have a constructor without parameter).
    I know that virtual inheritance may not be the best option, but I would like to know the answer to this problem anyway.

    Thanks in advance,
    Harinezumi
    I'm not sure if this is right,but I think you must specify in initializer list of Final class constructor a call to Base assignment constructor to overide calling of default constructor.

    Comment

    • Harinezumi
      New Member
      • Feb 2008
      • 32

      #3
      Originally posted by Savage
      I'm not sure if this is right,but I think you must specify in initializer list of Final class constructor a call to Base assignment constructor to overide calling of default constructor.
      If I do that, the compiler will not complain. However, why should a derived class have to initialize its indirect base? It doesn't make sense in my opinion.

      Comment

      • Savage
        Recognized Expert Top Contributor
        • Feb 2007
        • 1759

        #4
        Originally posted by Harinezumi
        If I do that, the compiler will not complain. However, why should a derived class have to initialize its indirect base? It doesn't make sense in my opinion.
        Derived classed calls they parent constructors and destructors(if no virtual destructor is specifed).By default they call default constructor,so if you want to overide this behaviour you must(probably) specify other constructor in initializer list.

        Comment

        • Harinezumi
          New Member
          • Feb 2008
          • 32

          #5
          But doesn't the specified constructor of VDer do that? It does call the constructor of Base. It definitely works that way, when virtual inheritance is not involved.

          Comment

          • Savage
            Recognized Expert Top Contributor
            • Feb 2007
            • 1759

            #6
            Originally posted by Harinezumi
            But doesn't the specified constructor of VDer do that? It does call the constructor of Base. It definitely works that way, when virtual inheritance is not involved.
            Yes it does that,when virtual inheritnace is not involved.As you know virtual inheritance is a method of solving diamond problem of multiple inheritance,so it is intended to be used like a multiple inheritance.If you remove virtual keyword form VDer class definition it will work without the need of base constructor.

            I googled about this on net and found something interesting:


            Originally posted by http://www.parashift.c om/c++-faq-lite/multiple-inheritance.htm l#faq-25.14

            Initialization list of most-derived-class's ctor directly invokes the virtual base class's ctor.

            Because a virtual base class subobject occurs only once in an instance, there are special rules to make sure the virtual base class's constructor and destructor get called exactly once per instance. The C++ rules say that virtual base classes are constructed before all non-virtual base classes. The thing you as a programmer need to know is this: constructors for virtual base classes anywhere in your class's inheritance hierarchy are called by the "most derived" class's constructor.

            Practically speaking, this means that when you create a concrete class that has a virtual base class, you must be prepared to pass whatever parameters are required to call the virtual base class's constructor. And, of course, if there are several virtual base classes anywhere in your classes ancestry, you must be prepared to call all their constructors. This might mean that the most-derived class's constructor needs more parameters than you might otherwise think.
            Anyway,I don't understand why are you using virtual inheritance when no multiple inheritance is involved in your case?

            Comment

            • Harinezumi
              New Member
              • Feb 2008
              • 32

              #7
              Thanks, Savage, for the info! The missing piece of information was that when using virtual inheritance the most derived class needs to call the virtual base class.

              Originally posted by Savage
              Anyway,I don't understand why are you using virtual inheritance when no multiple inheritance is involved in your case?
              In the given example I don't use multiple inheritance, because I reduced the code to the smallest chunk the problem appears in. However, the full code does use multiple inheritance.

              Comment

              Working...