Reputation: 95968
When I want to disallow class copy in C++, I usually declare a private operator= and a copy constructor and I don't implement them:
class MyClass
{
char* _str;
int _len;
MyClass(const MyClass& rhs); //No implementation
MyClass& operator=(const MyClass& rhs); //No implementation
public:
MyClass();
MyClass(const char *);
}
Is this considered a bad style? Is there another way to do this?
Upvotes: 3
Views: 577
Reputation: 64223
There are two ways, and both would cause a compilation errors :
C++11 way:
class MyClass
{
char* _str;
int _len;
MyClass(const MyClass& rhs) = delete;
MyClass& operator=(const MyClass& rhs) = delete;
public:
MyClass();
MyClass(const char *);
};
C++03 way:
class MyClass
{
char* _str;
int _len;
public:
MyClass();
MyClass(const char *);
MyClass(const MyClass& rhs); //No implementation
MyClass& operator=(const MyClass& rhs); //No implementation
}
If you just declare copy constructors public, you'll get linker errors, but the compilation will pass. Since the compilation happens before linking, breaking the compilation is better, because you'll catch the errors sooner.
Upvotes: 2
Reputation: 76808
In C++11 you can explicitly delete these functions (which is preferred over omitting the implementation, because it is more readable, and it will always generate a compiler-error, and not just a linker-error):
class MyClass
{
char* _str;
int _len;
MyClass(const MyClass& rhs) = delete;
MyClass& operator=(const MyClass& rhs) = delete;
public:
MyClass();
MyClass(const char *);
}
In C++03 you can use a base-class such as boost::noncopyable
to achieve the same effect. This might be more readable (this is essentially the same approach as yours - this base-class has private copy-constructor and assignment-operator, so inheriting from it will make your class uncopyable):
class MyClass : boost::noncopyable
{
char* _str;
int _len;
public:
MyClass();
MyClass(const char *);
}
The difference between shallow and deep copying in C++ rests entirely in how you implement your copy-constructor (because your assignment operator should be implemented using your copy-constructor). If you don't have one, neither shallow nor deep copying is possible, if you have, it depends on how it is implemented.
Upvotes: 10
Reputation: 42944
You can create a preprocessor macro to achieve the same thing, e.g.
#define DISABLE_COPY_AND_ASSIGN(className) private: \
className(const className&); \
className& operator=(const className&);
and then use it like this:
class MyClass
{
DISABLE_COPY_AND_ASSIGN(MyClass)
public:
....
};
You can derive from boost::noncopyable
as well:
class MyClass : boost::noncopyable
{
public:
....
};
Moreover, in C++11, you can use = delete
:
MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;
Upvotes: 3