Re: Non-default copy constructors & assignment operators are harmful?
Tim Conkling schrieb:
(I know that default compiler-supplied copy constructors and
assignment operators can be harmful for other reasons, but it's nice
that you don't have to remember to update them when you change a class
declaration.)
This position strongly depends on the eye of observer, v.i.
Design patterns like RAII help with some invisible dependencies -- by
eliminating the need to remember to always explicitly free a resource
after it's been required. Is there a pattern in C++ that can help
eliminate the need to keep class declarations and copy constructors/
assignment operators in sync? Are there patterns in other languages
that help with this sort of issue?
Indeed, indirectly RAII can help you here. You could (and should)
simply
use the compiler generated versions of the copy-c'tor and
copy assignment operator, if every member and base class has
the proper versions of these. I mean 'proper' in the sense, that you
don't need to write explicit code for it, that is these functions are
accessible
and do the correct stuff for your hosting class.
You can use some indicators for this: E.g. the rule of three: If you
need
to write explicit code for one of (a) destructor (b) copy-constructor
(c)
copy assignment op, you probably need to write all three. Such a class
can usually not use the compiler-generated versions. But maybe you
are lucky and this "defect" is due to a single member, which can be
repaced by a corresponding RAII class (e.g. shared_ptr), but mostly
these are not copyable, so I mentioned only the copyable version here.
A nice idiom under many (but not all) circumstances is that you only
write the copy-c'tor and a swap function (This makes sense, if swap
is already needed, useful, and has a low complexity) and to define
the copy assignment op. in terms of these two:
struct Example {
Example(const Example&); // Define this!
Example& operator=(const Example& rhs) {
Example(rhs).swap(*this);
return *this;
}
void swap(Example&); // Define this!
....
};
There exists people (not me) which prefer the even shorter
version
Example& Example::operator=(Example rhs) {
rhs.swap(*this);
return *this;
}
Greetings from Bremen,
Daniel Kr|gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]