🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #1908

Re: virtual base class construction

#1908
From: J. Kanze
Date: Tue, 05 Sep 1995 05:07
98 lines
4498 bytes
Scott Meyers (smeyers@netcom.com) wrote:
|> Distribution:
|> In article <MATT.95Aug29110526@physics10.Berkeley.EDU> kanze@gabi-soft.fr (J. Kanze) writes:
|> | Distribution:
|> | John Max Skaller (maxtal@Physics.usyd.edu.au) wrote:
|> | |> In article <40g1nl$2jo@gabi.gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
|> | |> >John Max Skaller (maxtal@Physics.usyd.edu.au) wrote:
|> | |> >
|> | |> >|> 	For example how do you do assignments in the presence of
|> | |> >|> virtual bases? What stops the data of the virtual base being assigned
|> | |> >|> more than once?
|> | |> >
|> | |> >	C&
|> | |> >	C::operator( C const& other )
|> | |> >	{
|> | |> >		if ( this != &other )
|> | |> >		{
|> | |> >			this->~C() ;
|> | |> >			new ( this ) C( other ) ;
|> | |> >		}
|> | |> >		return *this ;
|> | |> >	}
|> | |> >
|> | |> >No duplicate assignment of the virtual bases of C.
|> | 
|> | |> I don't understand, this does NOT work.
|> | 
|> | Yes it does.  At least, it does according to the standard, and on all
|> | compilers I've been able to try it with.  (It doesn't compile under
|> | certain versions of cfront, due to a compiler error.)

|> | The whole questions hinges on defining what the right thing is.  I would
|> | contend that in many (most?) cases, the right thing is to destruct the
|> | existing target object, and copy the right hand side into it.  This is
|> | *exactly* what my code does.
|> | 
|> | Since it uses the destructor for destruction, and the copy constructor
|> | for copying, *and* the compiler is required to do these correctly, it
|> | ``works''.
|> | 
|> | Note that typically, it will in fact do extra work, since the generated
|> | code will fiddle around with the vptr's.

|> The trick works, but at the risk of changing the dynamic type of the target
|> of the assignment.  For example:

|>   class A {};
|>   class B: virtual public A{};
|>   class C: virtual public A{};
|>   class D: public B, public C {};

|>   B *pb1 = new D;
|>   B *pb2 = new D;

|>   *pb1 = *pb2;         // calls B::operator= and changes the dynamic
|>                        // type of *pb1 to B, because its vtbl gets 
|>                        // changed

|> Note that this is not a problem with MI, it's a problem with the
|> implementation strategy that James proposed.  The same problem arises under
|> SI.

I knew there was a reason that you didn't like it.  (I also knew that
the reason pretty much convinced my at the time you first presented it.
I cannot say that I really like the trick, only that in the presence of
virtual base classes, I like the alternatives less.)

|> In fairness, assignment in the presence of inheritance is always tricky.
|> For example, my code above performs a partial assignment (due to the
|> call to B::operator=) unless operator= is declared virtual.  And if it's
|> declared virtual, you have to figure out what to do with mixed type
|> assignments like this:

|>   A *pa1 = new C;
|>   A *pa2 = new B;

|>   *pa1 = *pa2;     // assign a B to a C via C::operator=

You also end up with a plethora of operator='s in the derived classes,
since ``operator=( D const* )'' does *not* override ``operator=( B
const* )''.

In cases where polymorphism is important, I tend to work with reference
semantics, and assign smart pointers (or even ordinary pointers).  I
also furnish a `clone' function, so in the cases where deep copy is
appropriate, the user has that option.
-- 
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID: <MATT.95Sep04210712@Austern>
Path: arc1-ca.pugleaf.net!howland.reston.ans.net!agate!agate!Matt
References: <40g1nl$2jo@gabi.gabi-soft.fr> <40nvlf$al@metro.ucc.su.OZ.AU> <MATT.95Aug29110526@physics10.Berkeley.EDU> <MATT.95Aug30112934@Austern>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!howland.reston.ans.net!agate!agate!Matt
From: kanze@gabi-soft.fr (J. Kanze)
Newsgroups: comp.std.c++
Subject: Re: virtual base class construction
Date: 05 Sep 1995 05:07:12 GMT
Organization: GABI Software, Sarl.
Approved: Matt@Austern
Message-ID: <MATT.95Sep04210712@Austern>
References: <40g1nl$2jo@gabi.gabi-soft.fr> <40nvlf$al@metro.ucc.su.OZ.AU> <MATT.95Aug29110526@physics10.Berkeley.EDU> <MATT.95Aug30112934@Austern>
NNTP-Posting-Host: austern.hip.berkeley.edu