| View previous topic :: View next topic |
| Author |
Message |
Thiago Adams Guest
|
Posted: Wed May 09, 2007 3:14 pm Post subject: virtual operator = |
|
|
Can anyone imagine one reason to create the "operator =" virtual?
class X {
....
virtual X & operator = (const X &) { ... }
....
}
I didn't find any.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Mathias Gaunard Guest
|
Posted: Wed May 09, 2007 7:38 pm Post subject: Re: virtual operator = |
|
|
On May 9, 5:14 pm, Thiago Adams <thiago.ad...@gmail.com> wrote:
| Quote: | Can anyone imagine one reason to create the "operator =" virtual?
class X {
...
virtual X & operator = (const X &) { ... }
...
}
I didn't find any.
|
class Base
{
virtual Base& operator=(const Base&) = 0;
};
class Derived1 : public Base
{
Base& operator=(const Base&)
{
// the code for Derived1
}
};
class Derived2 : public Base
{
Base& operator=(const Base&)
{
// the code for Derived2
}
};
Derived1 d1;
Derived2 d2;
Base& b = d1;
b = d2; // virtual operator= needed here
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Risto Lankinen Guest
|
Posted: Wed May 09, 2007 7:39 pm Post subject: Re: virtual operator = |
|
|
On 9 touko, 18:14, Thiago Adams <thiago.ad...@gmail.com> wrote:
| Quote: | Can anyone imagine one reason to create the "operator =" virtual?
class X {
...
virtual X & operator = (const X &) { ... }
...
}
|
To prevent object slicing. Object slicing happens, when only
the base class sub-part of a derived object is manipulated by
e.g. functions that don't know the instance is really a derived.
Here's an outline:
- - -
struct Base
{
virtual Base &operator=( const Base &rhs )
{
// assign '*this' using 'rhs'
return *this;
}
};
struct Derived : Base
{
virtual Base &operator=( const Base &rhs )
{
Derived *p = dynamic_cast<Derived *>(&rhs);
if( p )
{
// Note that this fwd's to virtual Derived: p=() which
// can be similarly overridden by some hyperclass.
return *this = *p;
}
else
{
// Slicing that would have occurred is now caught!
// Assign the Base-part of this using 'rhs' and do the
// right thing with the Derived-part to retain invariants.
}
}
virtual Derived &operator=( const Derived &rhs )
{
// assign '*this' using 'rhs'
return *this;
}
};
- - -
Cheers!
- Risto -
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Niels Dekker - no return Guest
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Wed May 09, 2007 8:15 pm Post subject: Re: virtual operator = |
|
|
Thiago Adams <thiago.adams (AT) gmail (DOT) com> writes:
| Quote: | Can anyone imagine one reason to create the "operator =" virtual?
|
Yes.
| Quote: | class X {
...
virtual X & operator = (const X &) { ... }
|
Not this one though. This is the copy-assignment operator, which is a
special beast.
I don't see a reason for not making a different assignment operator,
with a source type unrelated to X's class hierarchy, virtual.
| Quote: | }
I didn't find any.
|
And why do you ask?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Thiago Adams Guest
|
Posted: Thu May 10, 2007 1:12 am Post subject: Re: virtual operator = |
|
|
Thanks everyone for the links and answers.
I asked because I want to write the advice: "Don't create the virtual
operator =" and I was trying to find out if it could be useful in some
cases.
I believe that for polymorphic objects the best way is to provide the
function Clone() and always to use pointers or references. In this
scenario the "copy" means: destroy and create a new one.
If the objects are the same type verified by typeid we could use the
same memory and the inplace new as an optimization.
I think that is not useful because is too much code and probably one
smart allocator can resolve the optimization problem.
Well I did one experiment for fun.
class base
{
virtual base * Clone() = 0;
virtual void ImplaceClone(base *) = 0;
public:
virtual ~base() {};
void CopyTo(base *& p)
{
// is the same type?
if (p && typeid(*this) == typeid(*p))
{
(*p).~base(); // destroy
ImplaceClone(p); // utilize the same memory
}
else //different
{
delete p; //delete
p = Clone(); // create a new one
}
}
};
#define POLYMORPHIC_COPY_IMP(Class)\
Class * Clone() { return new Class(*this); } \
void ImplaceClone(base * p) { new (p) Class(*this); }
class derived : public base
{
POLYMORPHIC_COPY_IMP(derived);
};
class derived2 : public base
{
POLYMORPHIC_COPY_IMP(derived2);
};
int main()
{
derived d;
base *p = 0;
d.CopyTo(p); // create a copy
derived d1;
d1.CopyTo(p); // create a copy using the same memory
derived2 d2;
d2.CopyTo(p); // delete and create a copy
}
Advices:
- Don't create the "operator =" for polymorphic types. Provide it for
concrete types.
- For polymorphic types use the Clone function.
- Don't make your code more complicated :)
Everyone agrees with these advices?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|