在C ++中禁止复制构造函数的最可靠方法是什么?

时间:2011-04-18 11:22:31

标签: c++ constructor class-design copy-constructor

有时需要禁止C ++类中的复制构造函数,以便该类变为“不可复制”。当然,operator=应该同时被禁止。

到目前为止,我已经看到了两种方法。方法1是将方法声明为私有,并且不给它实现:

class Class {
//useful stuff, then
private:
    Class( const Class& ); //not implemented anywhere
    void operator=( const Class& ); //not implemented anywhere
};

方法2是将方法声明为private并将其赋予“空”实现:

class Class {
//useful stuff, then
private:
    Class( const Class& ) {}
    void operator=( const Class& ) {}
};

IMO第一个更好 - 即使有一些意外的原因导致从同一个类成员函数调用复制构造函数,稍后会出现链接器错误。在第二种情况下,这个场景在运行时才会被忽视。

第一种方法有任何严重的缺点吗?什么是更好的方式,如果有的和为什么?

6 个答案:

答案 0 :(得分:27)

第一个更好

更好的是C++0x 'delete' keyword

class Class {
// useful stuff, then
public:
    Class(const Class&) = delete;
    void operator=(const Class&) = delete;
};

答案 1 :(得分:16)

第一种方法是Boost如何解决它(source code),据我所知,没有任何缺点。实际上,链接器错误是该方法的一大优势。您希望错误发生在链接时,而不是在客户端执行代码时它会突然崩溃。

如果你正在使用Boost,你可以节省一些打字。这跟你的第一个例子一样:

#include <boost/utility.hpp>

class Class : boost::noncopyable {
// Stuff here
}

答案 2 :(得分:7)

您始终可以从boost::noncopyable继承。

否则我从未见过数字2优于数字1的原因,因为它允许你在朋友或类方法中“复制构造”一个​​对象,即使它实际上不会创建对象的真实副本。

答案 3 :(得分:3)

由于其他答案提出了其他建议,并没有真正尝试回答这个问题,所以这是我的尝试:

那么哪种方法更好?这取决于你如何定义禁止复制

如果你想阻止其他人(只有非朋友的类和功能)复制,同时允许朋友和成员函数进行复制,那么第二种方法就是可行的方法。

如果您想阻止所有人(朋友,非朋友,会员功能)进行复制,那么第一种方法是唯一正确的解决方案。

请注意,第二种方法不会阻止朋友和成员函数复制(即调用复制函数) 1

1。如果你没有在第二种情况下正确定义它们,那么复制将无法正常工作,但这完全是另一回事。但重点是第二种情况并不妨碍调用复制函数。编译器不会生成任何错误消息。

答案 4 :(得分:2)

你的第一种方法没有任何缺点,我一直用它来制作“不可复制”的课程。

答案 5 :(得分:1)

我个人认为你已经回答了自己的问题,应该使用第一种方法。

如果您不希望它完全可复制,正如您所说,它将引发链接器错误。但是,如果您使用第二种方法,并且您最终意外地使用了复制构造函数,它将进行编译并且将运行;在你打开调试器之前,你绝对没有迹象表明不一致的地方。或者如上所述,如果您可以使用现代编译器,请使用C ++ 11的'= delete'表示法。