当我想在C ++中禁止类复制时,我通常会声明私有运营商= 和复制构造函数而我不会实施它们:
class MyClass
{
char* _str;
int _len;
MyClass(const MyClass& rhs); //No implementation
MyClass& operator=(const MyClass& rhs); //No implementation
public:
MyClass();
MyClass(const char *);
}
这被认为是一种糟糕的风格吗?还有另一种方法吗?
答案 0 :(得分:10)
在C ++ 11中,您可以显式删除这些函数(这比删除实现更受欢迎,因为它更易读,并且它总是会生成编译器错误,而不仅仅是链接器错误):
class MyClass
{
char* _str;
int _len;
MyClass(const MyClass& rhs) = delete;
MyClass& operator=(const MyClass& rhs) = delete;
public:
MyClass();
MyClass(const char *);
}
在C ++ 03中,您可以使用诸如boost::noncopyable
之类的基类来实现相同的效果。这可能更具可读性(这与您的方法基本相同 - 这个基类具有私有拷贝构造函数和赋值运算符,因此继承它将使您的类不可复制):
class MyClass : boost::noncopyable
{
char* _str;
int _len;
public:
MyClass();
MyClass(const char *);
}
C ++中浅层和深层复制之间的区别完全在于如何实现复制构造函数(因为your assignment operator should be implemented using your copy-constructor)。如果你没有,那么既不能进行浅层复制也不能进行深度复制,如果有的话,则取决于它的实现方式。
答案 1 :(得分:3)
您可以创建预处理器宏来实现相同的目的,例如
#define DISABLE_COPY_AND_ASSIGN(className) private: \
className(const className&); \
className& operator=(const className&);
然后像这样使用它:
class MyClass
{
DISABLE_COPY_AND_ASSIGN(MyClass)
public:
....
};
您也可以从boost::noncopyable
派生:
class MyClass : boost::noncopyable
{
public:
....
};
此外,在C ++ 11中,您可以使用= delete
:
MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;
答案 2 :(得分:2)
有两种方法,都会导致编译错误:
C ++ 11方式:
class MyClass
{
char* _str;
int _len;
MyClass(const MyClass& rhs) = delete;
MyClass& operator=(const MyClass& rhs); = delete
public:
MyClass();
MyClass(const char *);
};
C ++ 03方式:
class MyClass
{
char* _str;
int _len;
public:
MyClass();
MyClass(const char *);
MyClass(const MyClass& rhs); //No implementation
MyClass& operator=(const MyClass& rhs); //No implementation
}
如果您只是将复制构造函数声明为public,则会出现链接器错误,但编译将通过。由于编译在链接之前发生,因此打破编译会更好,因为你会更快地发现错误。