参见标题。
我有:
class Foo {
private:
Foo();
public:
static Foo* create();
}
从这里开始,我需要做什么才能使Foo无法复制?
谢谢!
Answers:
class Foo {
private:
Foo();
Foo( const Foo& ); // non construction-copyable
Foo& operator=( const Foo& ); // non copyable
public:
static Foo* create();
}
如果您使用的是boost,还可以从不可复制继承:http : //www.boost.org/doc/libs/1_41_0/boost/noncopyable.hpp
编辑:C ++ 11版本,如果您有支持此功能的编译器:
class Foo {
private:
Foo();
public:
Foo( const Foo& ) = delete; // non construction-copyable
Foo& operator=( const Foo& ) = delete; // non copyable
static Foo* create();
}
注意删除的方法应该是公开的:https : //isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-delete
#include <boost/utility.hpp>
class Foo : boost::noncopyable {...
但是正如斯科特·迈耶斯(Scott Meyers)曾经说过的那样……“这是一个很好的课程,只是我发现这个名称有点不合常理,而且很不自然”,或者类似的意思。
禁止复制构造函数的另一种方法,为方便起见,可以使用DISALLOW_COPY_AND_ASSIGN宏:
// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
void operator=(const TypeName&) = delete
然后,在Foo类中:
class Foo {
public:
Foo(int f);
~Foo();
private:
DISALLOW_COPY_AND_ASSIGN(Foo);
};
要添加一点。
传统的解决方案是,正如人们所说的,要宣布双方Copy Constructor
和Assignment Operator
作为private
,而不是要定义它们。
private
,这将导致任何尝试使用它们但无法访问该类私有部分的人都出现编译时错误...undefined symbol
在链接时(如果在其中检查它们)或在运行时(尝试加载库时)以的形式出现错误,而导致错误(以及类本身)。当然,在第二种情况下,这很麻烦,因为您没有代码指示发生错误的文件和行,因此您必须自己检查代码。幸运的是,它仅限于您的课堂方法和朋友。
此外,值得注意的是,这些属性是传递下来继承和组合的道路:编译器将仅生成的默认版本Default Constructor
,在Copy Constructor
中,Assignment Operator
和Destructor
它是否可能。
这意味着对于这四个类别中的任何一个,只有当它们对于该类的所有基础和属性都可访问时,它们才会自动生成。
// What does boost::noncopyable looks like >
class Uncopyable {
public:
Uncopyable() {}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
这就是为什么从此类继承(或将其用作属性)将有效地防止您自己的类可复制或可分配的原因,除非您自己定义这些运算符。
通常,选择继承而不是那里的组成有两个原因:
Uncopyable
,即使多态性可能没有那么有用EBO
或Empty Base Optimization
,而属性将是可寻址的,因此将占用内存(在该类的每个实例中),即使实际上并不需要它,编译器也有可能不为基类增加此开销。或者,您可以声明运算符为私有,而不是在您自己的类中定义它们,但是代码的自记录性会降低,并且您将无法自动搜索那些具有该属性的类(除非您拥有完整的解析器)。
希望这能对机制有所启发。
Uncopyable
如果没有显式定义构造函数,是不是不完整,因为不会由于其他构造函数的存在而自动生成它?例如,您将获得“没有合适的默认构造函数”,它是:rextester.com/SFWR22041感谢您的帮助!我特别感谢您使用继承的动力。
使C ++对象不可复制的典型方法是显式声明一个复制构造函数和一个复制分配运算符,但不实现它们。这将阻止编译器生成自己的编译器。(通常,这是与声明它们一起进行的,private
以便它生成编译错误而不是链接程序错误。)
还有boost::noncopyable
一个您可以从其继承的类,它可以完成我上面描述的工作。
将复制构造函数设为私有。
Foo(const Foo& src);
您不需要实现它,只需在头文件中声明它即可。
这是我用的:
/* Utility classes */
struct NoCopy
{
public:
NoCopy() {}
private:
NoCopy(const NoCopy &);
};
struct NoAssign
{
private:
NoAssign &operator=(const NoAssign &);
};
struct NonInstantiable
{
private:
NonInstantiable();
};
struct NoCopyAssign : NoCopy, NoAssign
{
};
typedef NoCopyAssign NoAssignCopy;
在您的情况下:
struct Example : NoCopy
{
};
C ++ 11中的一个好习惯是将副本构造函数和赋值声明为公开删除。未私下删除,公开删除:https : //isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-delete