请看标题。
我有:
class Foo {
private:
Foo();
public:
static Foo* create();
}
我需要从这里做什么才能使Foo无法复制?
请看标题。
我有:
class Foo {
private:
Foo();
public:
static Foo* create();
}
我需要从这里做什么才能使Foo无法复制?
class Foo {
private:
Foo();
Foo( const Foo& ); // non construction-copyable
Foo& operator=( const Foo& ); // non copyable
public:
static Foo* create();
}
如果你正在使用boost,你还可以继承noncopyable:
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将复制构造函数和赋值运算符也设为私有。只需声明即可,无需提供实现。
= delete
来显式禁用默认复制和赋值构造函数。struct NonCopyable {
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable & operator=(const NonCopyable&) = 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);
};
在这里补充一下。
传统的解决方案就是,正如先前提到的那样,将复制构造函数和赋值运算符都声明为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
或空基类优化
,而属性将是可寻址的,因此即使它实际上不需要,它也会占据内存(在类的每个实例中),编译器有可能不为基类添加此开销。或者你可以将这些运算符声明为私有,并且不在自己的类中定义它们,但代码会更少“自我记录”,并且您将无法自动搜索具有此属性的类(除非您有一个完整的解析器)。
希望这能解释这个机制。
Uncopyable
不是不完整的吗?因为由于存在其他构造函数,它将不会自动生成。例如,您将使用此代码获得“没有适当的默认构造函数可用”:http://rextester.com/SFWR22041 感谢您有益的答案!我特别欣赏您提供的继承动机。 - chappjcboost::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
{
};