Re: virtual inheritance nightmare

From: Victor Bazarov (v.Abazarov_at_comAcast.net)
Date: 12/29/04


Date: Wed, 29 Dec 2004 11:05:11 -0500

Gianni Mariani wrote:
> In the code below, controller::controller() is never invoked, however,
> it appears there is no way to make a compile-time rule that this should
> not happen. The code below seems to make compilers complain that
> controller::controller() is private, even though it is never used.

But it _might_ be used if you derive from Interface and make that class
concrete.

> What do others do to work-around this ? I suppose I can simply
> not implement controller::controller(), that way I get a linking
> error if there exists errant code. (ok tried that - gcc seems to
> detect errors and all is fine, MSVC seems to need the constructor
> even though it should never be invoked.)

But Impl1 and Impl2 also don't have default c-tors... And those _are_
invoked, no?

>
> Especially when a class has no way of being constructed alone (due to
> pure virtual methods), there should be not reason to access default
> virtual constructors since they can never be called hence there should
> be no violation of the access rule.

That's a QOI issue, I believe.

>
> class controller
> {
> controller(); // private don't want anyone to call this
> public:
> controller( int ); // this should be called instead
> };
>
> class Interface
> : virtual public controller
> {
> public:
> virtual void DoThing() = 0;
> };

As is, 'Interface' cannot have a default c-tor because its base class,
'controller' cannot be instantiated. Right?

>
> class Interface_Impl1
> : public Interface
> {
> public:
>
> virtual void DoThing1() = 0;
>
> virtual void DoThing()
> {
> DoThing1();
> }
> };

Now, 'Interface_Impl1' cannot have the default c-tor since 'Interface',
which is its base class, cannot have one. Right?

>
> class Interface_Impl2
> : public Interface
> {
> public:
>
> virtual void DoThing2() = 0;
>
> virtual void DoThing()
> {
> DoThing2();
> }
> };

Now, 'Interface_Impl2' cannot have the default c-tor as well, due to the
same reason as the 'Interface_Impl1'. Right?

>
> class Interface_Impl3
> : public Interface
> {
> public:
>
> virtual void DoThing()
> {
> // doing 3
> }
> };
>
> class Application
> : public Interface_Impl1,
> public Interface_Impl2
> {
> Application()
> : controller( 3 )

Wait... Here 'Interface_Impl1' and 'Interface_Impl2' _are_ instantiated
using their default c-tor, which cannot be generated because... See above.

> {
> }
>
> void DoThing1()
> {
> // Doing 1 it here !
> }
>
> void DoThing2()
> {
> // Doing 2 it here !
> }
> };

The work-around here (as I see it) is to declare 'Interface*' constructors
to accept a single argument and give it a default value. Since the final
class 'Application' will provide the argument for 'controller', the other
argument (although you will thread it through to the 'controller's c-tor)
will not have any effect. Of course, you will have to initialise the
virtual base 'controller' in each of 'Interface*' constructors too, but
that, again, should have no effect on your code, since 'Application' takes
over.

BTW, your 'Application's constructor is also private.

V



Relevant Pages

  • Re: writing drivers using C++
    ... declaration will lead to a subroutine invocation. ... Whether a class has overloaded operators is part of ... the interface of that class, ... Without using classes whose constructors allocate ressources in need ...
    (comp.os.linux.development.system)
  • Re: writing drivers using C++
    ... Whether a class has overloaded operators is part of ... the interface of that class, ... 'cleanup code' can often be avoided (eg by allocating ... temporary buffers of any kind on the stack, which constructors cannot ...
    (comp.os.linux.development.system)
  • Re: 7.0 wishlist?
    ... Any object can be used where an interface type is expected if it has the right set of method signatures, whether or not it "implements" the interface using that keyword. ... More typing than a single punctuation mark, by a factor of eight -- nearly an order of magnitude. ... Works, but if the array doesn't need to be modifiable, creates a wasteful duplicate every time. ... all the collections really ought to have constructors that take an Iterable and just iterate over it. ...
    (comp.lang.java.programmer)
  • Newbie
    ... As a migrant from COBOL to Java, i was amazed to see a mainmethod of a ... C++ had a concept of copy constructors to handle pass by values (though i ... implementation without the need to define the interface methods.Are there ... such interface types and if so, ...
    (microsoft.public.dotnet.languages.csharp)