What's the most reliable way to prohibit a copy constructor in C++?
Sometimes it's necessary to prohibit a copy constructor in a C++ class so that class becomes "non-copyable". Of course, operator=
should be prohibited at the same time.
So far I've seen two ways to do that. Way 1 is to declare the method private and give it no implementation:
class Class {
//useful stuff, then
private:
Class( const Class& ); //not implemented anywhere
void operator=( const Class& ); //not implemented anywhere
};
Way 2 is to declare the method private and give it "empty" implementation:
class Class {
//useful stuff, then
private:
Class( const Class& ) {}
void operator=( const Class& ) {}
};
IMO the first one is better - even if there's some unexpecte开发者_StackOverflow中文版d reason that leads to the copy constructor being called from the same class member function there'll be a linker error later on. In the second case this scenario will be left unnoticed until the runtime.
Are there any serious drawbacks in the first method? What's a better way if any and why?
The first one is better
Even better is C++0x 'delete' keyword:
class Class {
// useful stuff, then
public:
Class(const Class&) = delete;
void operator=(const Class&) = delete;
};
The first method is how Boost solves it (source code), as far as I know, there's no drawbacks. In fact, the linker errors are the big advantage of that method. You want the errors to be at link time, not when your client is executing your code and it suddenly crashes.
In case you are using Boost, you can save yourself some typing. This does the same as your first example:
#include <boost/utility.hpp>
class Class : boost::noncopyable {
// Stuff here
}
You can always inherit from boost::noncopyable
.
Otherwise I've never seen a reason number 2 is better than number 1 as it will allow you to "copy construct" an object within friend or class methods even though it won't actually create a true copy of the object.
As other answers suggest something else, and doesn't really attempt to answer the question, so here is my attempt:
So which approach is better? It depends on how you define prohibit copy?
If you want to prevent others (only non-friend classes and functions) from copying while allowing friends and member-functions to copy, then second approach is the way to go.
If you want to prevent everyone (friends, non-friends, member-functions) from copying, then first approach is the only correct solution.
Note that the second approach does not prevent friends and member-functions from copying (that is, from calling the copy-functions). 1
1. If you don't properly define them in the second case, then copy wouldn't work, as expected, but that is a different thing altogether. But the point is that second case doesn't prevent from calling the copy-functions. The compiler wouldn't generate any error message.
There is no drawback in your first approach, I has been using that to make "non-copyable" class ..
Personally I think you've answered your own question, and should use the first approach.
If you don't want it to be copyable at all, as you said it will throw a linker error. However if you use the second approach and you DO end up using the copy constructor by accident, it WILL compile and it WILL run; and you'll have absolutely no indication of where the inconsistency came from until you bust open a debugger. Or as sehe said, if you can use a modern compiler, use C++11's '= delete' notation.
精彩评论