Re: Virtual bases and default move and swap functions [n2583, n2584]
Richard Smith wrote:
In a virtual inheritance hierarchy, the implicitly-declared assignment
operator is allowed to assign the base class multiple times
[[class.copy] 12.8/13]:
[ example snipped ]
Generally, this is not a problem, as it is fairly unusual to store
data in virtual bases, [...]
Is it really? I thought the point of virtual inheritance was to prevent
having separate copies of the data members from the same base class;
without any data members in the base, making the base virtual or
non-virtual wouldn't make much difference. Am I wrong?
Because in many cases, it would be virtually impossible (no pun
intended) for the compiler to do anything else. Imagine V, A and B
all have user-defined assignment operators, with implementations
buried away in a source file somewhere. In practice the
implementations of A and B are likely to look something like:
A& operator=( A const& o ) {
V::operator=(o);
// assign members
return *this;
}
[...]
Now, give this; and specifically given that the implementations of
A::operator=, B::operator= and V::operator= may not be visible to the
compiler, what should the compiler-generated D::operator= look like?
The only reasonable definition is:
D& operator=( D const& o ) {
A::operator=(o);
B::operator=(o);
// and then assign each member ...
return *this;
}
And this will generally double-assign the base class, V, because
A::operator= will assign it, and then B::operator= will do it again.
However, for most classes, the double assignment is safe -- it is
merely a slight inefficiency.
One way to prevent double assignment is, implementing separate
assignments by hand:
struct A : virtual V
{
void assign_without_V(A const&); // ignore the V part
A& operator=(A const& o) {
V::operator=(o);
assign_without_V(o);
return *this;
}
};
// similarly for B
struct D : A, B
{
D& operator=(D const& o) {
V::operator=(o);
A::assign_without_V(o);
B::assign_without_V(o);
return *this;
}
};
Yes, it's tedious, but AFAIK it's the only way to get it correct.
--
Seungbeom Kim
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]