Article View: comp.std.c++
Article #1908Re: virtual base class construction
From: J. Kanze
Date: Tue, 05 Sep 1995 05:07
Date: Tue, 05 Sep 1995 05:07
98 lines
4498 bytes
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!MattReferences:
<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