From: Mark_Galeck on
Hello,

how to write a non-default constructor for a class that inherits an
indirect base class, with multiple intermediate classes that list the
base as virtual? In the SSCCE below, the compiler complains "error:
no matching function for call to �Base::Base()". Thank you,

Mark

class Base {
public:
Base(int) {
}
};

class Intermediate0: public virtual Base {
public:
Intermediate0(int arg) :
Base(arg) {
}
};

class Intermediate1: public virtual Base {
public:
Intermediate1(int arg) :
Base(arg) {
}
};

class Derived: public Intermediate0, public Intermediate1 {
public:
Derived(int arg) :
Intermediate0(arg), Intermediate1(arg) {
}
};

main() {}



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Hyman Rosen on
On 6/2/2010 3:00 PM, Mark_Galeck wrote:
> how to write a non-default constructor for a class that inherits an
> indirect base class, with multiple intermediate classes that list the
> base as virtual?

Each derived class constructor must provide an initializer
for each virtual base class. Initializers provided for the
virtual bases in base class constructors are ignored.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Bo Persson on
Mark_Galeck wrote:
> Hello,
>
> how to write a non-default constructor for a class that inherits an
> indirect base class, with multiple intermediate classes that list
> the base as virtual? In the SSCCE below, the compiler complains
> "error: no matching function for call to ‘Base::Base()". Thank you,
>
> Mark
>
> class Base {
> public:
> Base(int) {
> }
> };
>
> class Intermediate0: public virtual Base {
> public:
> Intermediate0(int arg) :
> Base(arg) {
> }
> };
>
> class Intermediate1: public virtual Base {
> public:
> Intermediate1(int arg) :
> Base(arg) {
> }
> };
>
> class Derived: public Intermediate0, public Intermediate1 {
> public:
> Derived(int arg) :
> Intermediate0(arg), Intermediate1(arg) {
> }
> };
>
> main() {}

You should add Base(arg) to the initializer list of the most derived
class. That class will call the virtual base constructor, and the
intermediate classes will not. This is a special rule for virtual
bases (section 12.6.2 of the standard).


Bo Persson


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Salt_Peter on
On Jun 2, 3:00 pm, Mark_Galeck <clcppm-pos...(a)this.is.invalid> wrote:
> Hello,
>
> how to write a non-default constructor for a class that inherits an
> indirect base class, with multiple intermediate classes that list the
> base as virtual? In the SSCCE below, the compiler complains "error:
> no matching function for call to �Base::Base()". Thank you,
>
> Mark

That should be your clue. The derived class is looking for a default
ctor. And can't find any. Since the intermediate classes derive from a
virtual base, the Derived class should be invoking the Base ctor in
its init list.

>
> class Base {
> public:
> Base(int) {
> }
>
> };
>
> class Intermediate0: public virtual Base {
> public:
> Intermediate0(int arg) :
> Base(arg) {
> }

Intermediate0() { }

>
> };
>
> class Intermediate1: public virtual Base {
> public:
> Intermediate1(int arg) :
> Base(arg) {
> }

Intermediate1() { }

>
> };
>
> class Derived: public Intermediate0, public Intermediate1 {
> public:
> Derived(int arg) :
> Intermediate0(arg), Intermediate1(arg) {
> }

Derived(int arg) :
Intermediate0(),
Intermediate1(),
Base(arg) { }

>
> };
>
> main() {}

{ quoted banner removed; please do it yourself. -mod }

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: micode on
On Jun 2, 3:00 pm, Mark_Galeck <clcppm-pos...(a)this.is.invalid> wrote:
> Hello,
>
> how to write a non-default constructor for a class that inherits an
> indirect base class, with multiple intermediate classes that list the
> base as virtual? In the SSCCE below, the compiler complains "error:
> no matching function for call to �Base::Base()". Thank you,
>
> Mark
>
> class Base {
> public:
> Base(int) {
> }
>
> };
>
> class Intermediate0: public virtual Base {
> public:
> Intermediate0(int arg) :
> Base(arg) {
> }
>
> };
>
> class Intermediate1: public virtual Base {
> public:
> Intermediate1(int arg) :
> Base(arg) {
> }
>
> };
>
> class Derived: public Intermediate0, public Intermediate1 {
> public:
> Derived(int arg) :
> Intermediate0(arg), Intermediate1(arg) {
> }
>
> };
>
> main() {}

{ quoted banner removed; please do it yourself. -mod }

The non-trivial constructor should a default parameter or an explicit
call in a most derived class.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]