Sign in to follow this  

[C++] trouble with "public virtual" derived classes

This topic is 3731 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all, I've been going at this all day today, and still haven't made any progress. I have a base class, a few classes derived from the base (using public virtual), and a few other classes that join some or all of the derived classes together, based on what their functionality is. Code-wise (and very simplified), it looks something like this:
class Base
{
public:
    const char *   getName() const;

protected:
    Base(const char *name);
    virtual ~Base();

private:
    const char *name;
};


class A : public virtual Base
{
public:
    virtual void Afunc() = 0;

protected:
    A(const char *name);
    virtual ~A();
};


class B : public virtual Base
{
public:
    virtual void Bfunc() = 0;

protected:
    B(const char *name);
    virtual ~B();
};


class C : public virtual Base
{
public:
    virtual void Cfunc() = 0;

protected:
    C(const char *name);
    virtual ~C();
};


class Fred : public A, public C
{
public:
    Fred();
    ~Fred();

    void Afunc();
    void Cfunc();
};


class Mary : public A, public B, public C
{
    Mary();
    ~Mary();

    void Afunc();
    void Bfunc();
    void Cfunc();
};


Now, the constructors for Base, classes A-C, and Fred and Mary are defined as:
Base::Base(const char *name) : name(name)
{
}

A::A(const char *name) : Base(name)
{
}

B::B(const char *name) : Base(name)
{
}

C::C(const char *name) : Base(name)
{
}

Fred::Fred() : A("Fred"), C("Fred")
{
}

Mary::Mary() : A("Mary"), B("Mary"), C("Mary")
{
}


Every constructor is properly initialized with its own argument list. However, when compiling Fred or Mary, VS2005 gives the following error:
error C2512: 'Base::Base' : no appropriate default constructor available
gcc gives a slightly similar error, but the extra information isn't really all that helpful:
In constructor 'Fred::Fred()':
error: no matching function for call to 'Base::Base()'
note: candidates are: Base::Base(const char * name)
note:                 Base::Base(const Base::Base&)
From the looks of it, the errors seem to indicate a default constructor is required for some reason. This, to be blunt, is unacceptable, because I simply cannot initialize Base without a name. If I remove the "virtual" keyword when deriving classes A-C, the error goes away and everything compiles fine. However, this leads to problems since the "name" member variable in the Base class is being duplicated multiple times, depending on how Fred or Mary is implemented. (According to C++ FAQ Lite #25.9) As a test, I tried making a default constructor and used the debugger to see where the path of execution went. When Fred() was called, A() was never initialized and the default Base() was called. Is there something I'm missing here? Any help would be greatly appreciated.

Share this post


Link to post
Share on other sites
With virtual inheritance only the constructor call from the concrete type being constructed counts. In this case, Fred and Mary are the concrete types being constructed. All other constructors for virtual base classes are ignored. The consequence of that is that if the virtual base is not default constructible, then your most derived classes will need to pass parameters to the Base class constructor. So in your example code you would need:

Fred::Fred() : Base("Fred")
{
}

Share this post


Link to post
Share on other sites

This topic is 3731 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this