什么是最可靠的方法来禁止C + +的构造函数?
有时候,有必要禁止C ++类中的拷贝构造函数,以使类变为“不可拷贝”。 当然, operator=
应该同时被禁止。
到目前为止,我已经看到两种方式来做到这一点。 方法1是将方法声明为私有,并且不执行:
class Class { //useful stuff, then private: Class( const Class& ); //not implemented anywhere void operator=( const Class& ); //not implemented anywhere };
方法2是将私有方法声明为“空”实现:
class Class { //useful stuff, then private: Class( const Class& ) {} void operator=( const Class& ) {} };
海事组织的第一个更好 – 即使有一些意想不到的原因导致从同一个类成员函数调用复制构造函数将稍后会出现链接器错误。 在第二种情况下,这个场景直到运行时才会被忽略。
第一种方法有没有严重的缺陷? 什么是更好的方法,如果有的话,为什么?
第一种方法是Boost解决它( 源代码 ),据我所知,没有缺点。 事实上,链接器错误是该方法的一大优点。 你想要的错误是在链接的时候,而不是当你的客户端执行你的代码,它突然崩溃。
如果你正在使用Boost,你可以节省一些键入。 这和你的第一个例子是一样的:
#include <boost/utility.hpp> class Class : boost::noncopyable { // Stuff here }
第一个更好
更好的是C ++ 0x'删除'关键字 :
class Class { // useful stuff, then public: Class(const Class&) = delete; void operator=(const Class&) = delete; };
你总是可以从boost::noncopyable
inheritance。
否则,我从来没有见过一个理由2号比1号更好,因为它可以让你“复制构造”一个对象在朋友或类的方法,即使它不会真正创build对象的副本。
由于其他答案提出了其他的意见,并没有真正试图回答这个问题,所以这里是我的尝试:
那么哪种方法更好? 这取决于你如何定义禁止复制 ?
如果你想防止其他人(只有非朋友类和function)复制, 而允许朋友和会员function复制 ,那么第二种方法是要走的路。
如果要防止所有人 (朋友,非朋友,会员function)被复制,那么第一种方法是唯一正确的解决scheme。
请注意,第二种方法并不妨碍朋友和成员函数的复制(即调用复制函数) 。 1
1.如果在第二种情况下没有正确定义它们,那么复制将不会如预期的那样工作,但这完全是另一回事。 但重点是,第二种情况并不妨碍调用复制function。 编译器不会产生任何错误信息。
你的第一种方法没有什么缺点,我一直在用它来制作“不可复制”的类。
我个人认为你已经回答了你自己的问题,应该使用第一种方法。
如果你不希望它是可复制的,正如你所说,它会抛出一个链接器错误。 但是,如果你使用第二种方法,你最终会意外地使用复制构造函数,它会编译并运行; 你完全没有迹象表明不一致的地方,直到你打开一个debugging器。 或者如他所说,如果你可以使用现代编译器,使用C ++ 11的'= delete'符号。