From: maxtal@extro.ucc.su.OZ.AU
Newsgroups: comp.lang.c++
Date: 17 Jul 92 20:17 MDT
Subject: Re: Novice? question: Designing for mul
Nf-ID: #R:1992Jul9.144630.10863@clpd.kodak:653025985:1992Jul17.161720.28511@ucc.su.oz:-1685440123:001:3370
Nf-From: extro.ucc.su.OZ.AU!maxtal    Jul 17 20:17:00 1992


In article <rmartin.711298357@thor> rmartin@thor.Rational.COM (Bob Martin) writes:
>maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>|>
>|>|	WARNING: You can't do this using either cfront or Borlandc,
>|>|	both have faults preventing use of virtual abstract bases.
>|>
>|>MAX: This is far too strong a statement.  There are indeed some
>|>limitations, especially where virtual bases are concerned.  But you
>|>CAN make mixin heirarchies quite successfully.
>
>|	I don't agree. To use mixin properly you need orthogonal
>|classes. It is not possible to define an abstract 'diamond'
>|in Borlandc and use it. Test program is included right here.
>
>|// RE Abstract Classes
>|// some compilers work and others fail when #define KLUDGE is 
>|// commented out. Borlandc says D is abstract.
>|// CLEARLY it is not.
>|// However rewiting rules in ARM are not clear.
>|// It is essential for "mix-in" programming that D is concrete.
>|// as far as I know:
>|//  Broken: BorlandC (MY compiler), cfront (AT&T)
>|//  Work  : GNU++, MC7 (Microsoft)
>|//
>|#define KLUDGE
>|#ifndef KLUDGE
>|class V {public: virtual void f()=0; virtual void g()=0;};
>|#else
>|class V {public: virtual void f(){printf("ERROR V::g\n");} 
>|	virtual void g(){printf("ERROR V::g\n");}};
>|#endif
>|class A1 : public virtual V {public: void f(){printf("A1::f\n");}};
>|class A2 : public virtual V {public: void g(){printf("A2::g\n");}};
>|class D : public A1, public A2 {};
>|int main()
>|{
>|	D* d=new D;
>|	A1 * a1=d;
>|	A2 * a2=d;
>|	V * v = d;
>|	d->f(); a1->f(); a2->f(); v->f();
>|	d->g(); a1->g(); a2->g(); v->g();
>|}
>
>Yes, this is a problem.  There are ambiguities which are difficult to
>resolve when trying to fit a jigsaw set of methods together through
>MI.  Should pure virtual functions be preferentially overridden by
>implemented virtual function muliply inherited from a sibling?  I am
>sure that a counter example could be conceived.

	I am sorry, but you are quite wrong. There is NO PROBLEM with
overriding virtual functions. There is NO AMBIGUITY in the choice
of the correct function here: read ARM.

	The fact that it works when KLUDGE is defined PROVES that.
The problem is much simpler: Borland thinks D is abstract
and will not instantiate it, it is wrong. The definition
is ARM is misleading, but there can be no other sensible
interpretation.

>
>Still, this does not raise a hopless issue.  Your class D simply needs
>to be implemented in such a way that it declares f and g and calls the
>correct functions.  i.e. 
>	D::f() {A1::f();}
>	D::g() {A2::g();}
>
>This is something of a pain, but it is necessitated by the current
>rules of multiple inheritance.
>

	No, it works PROPERLY with KLUDGE defined. There is NO problem
resolving the virtual calls. D is concrete, not abstract,
Borland is simply wrong.

	Your solution is a pain in the proverbial but will force
D to be concrete. So will providing dummy bodies as I have
done above. Sometimes your solution is better, however.

	The best solution is for Borland and AT&T to fix their
broken compilers: Microsoft does not have this problem.

-- 
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
	Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------

Newsgroups: comp.lang.c++