Topic: Virtual Base-class constructor calls
Author: ken.durden@augusttech.com (Ken Durden)
Date: 30 Aug 2002 18:45:05 GMT Raw View
Any class which derives from a virtual base-class (through any number
of levels of inheritance), must call the constructor of the virtual
base class. The only invocation which is actually used, however, is
the one for the class actually being constructed.
Thus, in the following example classes B and C must call the A ctor
even though their invocation is never used since they are never
allocated.
My only suggestion is that B and C be permitted to not call the A ctor
since they are both pure virtual and cannot be allocated.
The solution I've used below works alright when the arguments are
simply, but it becomes a little harder when you start taking in
references to different types, or objects, etc...
-ken
struct A
{
A(int x) {}
virtual void f() = 0;
};
struct B : public virtual A
{
B() :
A(2) /* not used */
{}
};
struct C : public virtual A
{
C() :
A(2) /* not used */
{}
};
struct D : public B, public C
{
D() :
A(4),
B(),
C()
{}
};
int main()
{
D d;
}
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 30 Aug 2002 19:10:05 GMT Raw View
"Ken Durden" <ken.durden@augusttech.com> wrote...
> Any class which derives from a virtual base-class (through any number
> of levels of inheritance), must call the constructor of the virtual
> base class. The only invocation which is actually used, however, is
> the one for the class actually being constructed.
>
> Thus, in the following example classes B and C must call the A ctor
> even though their invocation is never used since they are never
> allocated.
>
> My only suggestion is that B and C be permitted to not call the A ctor
> since they are both pure virtual and cannot be allocated.
What if I write another class that derives from B but not
from C, and which implements f()? I will have no way to
initialise A, so I will have to rely on B's constructor for
the initialisation with a number.
>
> The solution I've used below works alright when the arguments are
> simply, but it becomes a little harder when you start taking in
> references to different types, or objects, etc...
What are you referring to? In your example D is still
abstract (since it doesn't provide a definition of f())
and initialising bases (B and C) in the D's c-tor is
completely unnecessary.
>
> -ken
>
>
> struct A
> {
> A(int x) {}
> virtual void f() = 0;
> };
>
> struct B : public virtual A
> {
> B() :
> A(2) /* not used */
"Not used" by whom?
> {}
> };
>
> struct C : public virtual A
> {
> C() :
> A(2) /* not used */
> {}
> };
>
> struct D : public B, public C
> {
> D() :
> A(4),
> B(),
> C()
> {}
You can do just
D() : A(4) {}
But you have to add
void f();
to be able to instantiate it.
> };
>
> int main()
> {
> D d;
Error: abstract class
> }
Victor
--
Please remove capital A's from my address when replying by mail
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Andrey Tarasevich <andreytarasevich@hotmail.com>
Date: 30 Aug 2002 20:00:05 GMT Raw View
Victor Bazarov wrote:
> ...
> > Any class which derives from a virtual base-class (through any number
> > of levels of inheritance), must call the constructor of the virtual
> > base class. The only invocation which is actually used, however, is
> > the one for the class actually being constructed.
> >
> > Thus, in the following example classes B and C must call the A ctor
> > even though their invocation is never used since they are never
> > allocated.
> >
> > My only suggestion is that B and C be permitted to not call the A ctor
> > since they are both pure virtual and cannot be allocated.
>
> What if I write another class that derives from B but not
> from C, and which implements f()? I will have no way to
> initialise A, so I will have to rely on B's constructor for
> the initialisation with a number.
> ...
I don't see how it makes any difference. 'A' is virtual base class of
'B'. Even if you define class, say, 'X' that derives only from 'B',
you'll still have to initialize 'A' from 'X's initializer list in 'X's
constructor. It doesn't matter whether there are five, two or only one
way from 'A' to 'X' in the inheritance diagram, a virtual base class
remains a virtual base class. It will always be initialized in
accordance with the initializer list in most derived object's
constructor.
I don't understand why you say "I will have no way to initialize A". Of
course you will have a way to initialize it.
Best regards,
Andrey Tarasevich,
Brainbench C and C++ Programming MVP
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: Fri, 30 Aug 2002 15:16:10 CST Raw View
"Andrey Tarasevich" <andreytarasevich@hotmail.com> wrote...
> Victor Bazarov wrote:
> > ...
> > > Any class which derives from a virtual base-class (through any number
> > > of levels of inheritance), must call the constructor of the virtual
> > > base class. The only invocation which is actually used, however, is
> > > the one for the class actually being constructed.
> > >
> > > Thus, in the following example classes B and C must call the A ctor
> > > even though their invocation is never used since they are never
> > > allocated.
> > >
> > > My only suggestion is that B and C be permitted to not call the A ctor
> > > since they are both pure virtual and cannot be allocated.
> >
> > What if I write another class that derives from B but not
> > from C, and which implements f()? I will have no way to
> > initialise A, so I will have to rely on B's constructor for
> > the initialisation with a number.
> > ...
>
> I don't see how it makes any difference. 'A' is virtual base class of
> 'B'. Even if you define class, say, 'X' that derives only from 'B',
> you'll still have to initialize 'A' from 'X's initializer list in 'X's
> constructor. It doesn't matter whether there are five, two or only one
> way from 'A' to 'X' in the inheritance diagram, a virtual base class
> remains a virtual base class. It will always be initialized in
> accordance with the initializer list in most derived object's
> constructor.
>
You're right, I'd forgotten the rule for virtual base classes.
I need to be less hasty and more attentive.
Victor
--
Please remove capital A's from my address when replying by mail
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]