# Assignment operator and virtual inheritance

## Recommended Posts

Aliii    1456

With virtual inheritance you can prevent a base class from being created more than once. So far I couldnt find a proper way to prevent the assignment/move-assignment operator from being called multiple times on the base. As for C++11 or 14, is there some new feature that makes this possible? If not, whats the best way to handle this? (apart from not putting any data into the base:)) Thanks!

##### Share on other sites
popsoftheyear    2194

Multiple times in a single invocation?

##### Share on other sites
Aliii    1456

You have the "dreaded diamond" hierarchy. You have virtual inheritance.

A
| \
|   \
B    C
|   /
| /
D

D d1;    //As constructor will be called once. Good
D d2;

d1 = d2; //D will call Bs and Cs operator=, and those both will call As. ....so it will be called twice.


Also, with move assignment, ...you are supposed to zero out the data in the source after youve copied it. So thats no good.

##### Share on other sites
popsoftheyear    2194

 I see - scratch my reply. You were talking about virtual inheritance.

Edited by achild

##### Share on other sites
popsoftheyear    2194

@Alvaro - Thanks, I eventually realized that - I was not familiar with virtual inheritance (I seldom use inheritance outside of GUIs and never use multiple inheritance except for the rare case of multiple interfaces)

The only solution I can think of is to override assignment yourself to ensure it does what you want, though you seem to be looking for a built in language feature.

Edited by achild

##### Share on other sites
popsoftheyear    2194

Out of curiosity, do you have a use case for this or is it purely theoretical?

##### Share on other sites
Aliii    1456

I do have a class: CObjectWithID. If you derive from it:

class CA : public CObjectWithID{ ....

class CB : public CObjectWithID{ ....

...it will automatically generate and maintain ID-s for objects of CA and CB. It uses the constructors, destructor, assignment operatorts for that. I dont wanna go too much into it, but the point is it works as long as you dont do something like this: class CA : public CB, public CObjectWithID{...

##### Share on other sites
Bregma    9199

Other than efficiency, why would it cause a problem to call the virtual base assignment operator twice, unless the virtual base class does not implement copy semantics?  If the only problem is efficiency, perhaps you should look at using a lighter-weight data representation.

##### Share on other sites
popsoftheyear    2194

Just wagering a guess here - but it looks like he has an ID system which gives new IDs to objects upon assignment. In this case 2 IDs would be generated... despite the number of design questions it raises, it's hard to tell with what we've been given if that is problematic or just annoying.

Edited by achild

##### Share on other sites
Erik Rufelt    5901

Seems very complicated... perhaps virtual assignment operators and/or making sure you can't assign a class to a different type.

I think implementing a swap() might be even worse.

##### Share on other sites
SeanMiddleditch    17565
First, just don't do this. You don't need virtual inheritance and you don't need a funky inheritance structure. Flatten your object relationships, use aggregation, prefer interfaces over base classes, etc. 20 years of C++ and I've never once run into a problem like this that couldn't be fixed with a smarter object structure (remember, computers aren't taxonomists, they don't care about real-world relationships when it comes to OOP; they only care about functional interfaces).

Second, this is the kind of question you should direct at StackOverflow for the language grognards to answer. You'd likely get a full answer with quotes from the standard in like 4.7 seconds if you had posted this over there.

##### Share on other sites
Aliii    1456

Second, this is the kind of question you should direct at StackOverflow for the language grognards to answer. You'd likely get a full answer with quotes from the standard in like 4.7 seconds if you had posted this over there.

Lol, you are right.

The first paragraph: I agree with most of it, thanks for the advice. I dont think I can talk about the parts I dont agree with without risking a debate/opinion-exchange. ...so I wont:)

##### Share on other sites
Hodgman    51220

That is an interesting question, but I agree that it probably shouldn't be a concern in practice.

Virtual & multiple inheritance are designed to be used with abstract interfaces... and it doesn't make much sense to have assignment operators for interfaces.
If I have an interface IStream and derived from it I have the implementations DiskStream and NetworkStream, what does it mean when a user writes:

NetworkStream n(...);
DiskStream d(...);
d = n;// "turn my disc-reading stream into a copy of my network-reading stream" WHAT DO YOU WANT FROM ME?!

In this case, I'd probably make IStream non-copyable.

##### Share on other sites
SmkViper    5396

That is an interesting question, but I agree that it probably shouldn't be a concern in practice.

Virtual & multiple inheritance are designed to be used with abstract interfaces... and it doesn't make much sense to have assignment operators for interfaces.
If I have an interface IStream and derived from it I have the implementations DiskStream and NetworkStream, what does it mean when a user writes:


NetworkStream n(...);
DiskStream d(...);
d = n;// "turn my disc-reading stream into a copy of my network-reading stream" WHAT DO YOU WANT FROM ME?!`
In this case, I'd probably make IStream non-copyable.

Obviously they want the hard drive to unplug itself from the SATA cable, jam a RJ45 in there, and access it via the network card.