ano*_*non 64 c++ copy-constructor noncopyable
见标题.
我有:
class Foo {
private:
Foo();
public:
static Foo* create();
}
Run Code Online (Sandbox Code Playgroud)
我需要做什么才能让Foo无法复制?
谢谢!
Kla*_*aim 89
class Foo {
private:
Foo();
Foo( const Foo& ); // non construction-copyable
Foo& operator=( const Foo& ); // non copyable
public:
static Foo* create();
}
Run Code Online (Sandbox Code Playgroud)
如果你正在使用boost,你也可以从noncopyable继承:http://www.boost.org/doc/libs/1_41_0/boost/noncopyable.hpp
编辑:C++ 11版本,如果您有一个支持此功能的编译器:
class Foo {
private:
Foo();
Foo( const Foo& ) = delete; // non construction-copyable
Foo& operator=( const Foo& ) = delete; // non copyable
public:
static Foo* create();
}
Run Code Online (Sandbox Code Playgroud)
yes*_*aaj 18
另一种禁止复制构造函数的方法,为方便起见,可以使用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
Run Code Online (Sandbox Code Playgroud)
然后,在Foo类中:
class Foo {
public:
Foo(int f);
~Foo();
private:
DISALLOW_COPY_AND_ASSIGN(Foo);
};
Run Code Online (Sandbox Code Playgroud)
Chr*_*s H 17
#include <boost/utility.hpp>
class Foo : boost::noncopyable {...
Run Code Online (Sandbox Code Playgroud)
但正如斯科特迈尔斯曾经说过的那样......"这是一个很好的课程,只是我发现这个名字有点不合适,不自然",或类似的东西.
Mat*_* M. 17
在那里添加一点.
传统的解决方案是,正如人们所说的,要宣布双方Copy Constructor和Assignment Operator作为private,而不是要定义它们.
private会导致编译时出错,任何试图使用它们的人都无法访问该类的私有部分...undefined symbol在链接时(或者在那里检查那些)或者最有可能在运行时(当尝试加载库时)以形式发生错误的朋友(以及类本身).当然,在第二种情况下是非常麻烦的,因为您必须自己检查代码,因为您没有指示发生错误的文件和行.幸运的是,它只限于你的班级方法和朋友.
此外,值得注意的是,这些属性在继承和组合之路上是传递的:编译器只生成Default Constructorthe Copy Constructor,the Assignment Operator和the Destructorif的默认版本.
这意味着对于这四个中的任何一个,只有当它们可以访问类的所有基础和属性时,它们才会自动生成.
// What does boost::noncopyable looks like >
class Uncopyable {
public:
Uncopyable() {}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
Run Code Online (Sandbox Code Playgroud)
这就是为什么从这个类继承(或者使用它作为属性)将有效地防止你自己的类可以被复制或分配,除非你自己定义这些运算符.
一般来说,选择继承是因为组合有两个原因:
Uncopyable即使多态性可能没那么有用,该对象也是有效的EBOor Empty Base Optimization,虽然属性是可寻址的,因此将占用内存(在类的每个实例中),即使它实际上不需要它,编译器也有可能不为基类添加这种开销.或者,您可以将运算符声明为私有而不是在您自己的类中定义它们,但代码将不那么自我记录,并且您将无法自动搜索那些具有此属性的类(除非您有完整的解析器).
希望这能为机制提供一些启示.
bob*_*uba 11
在C++ 11中,您可以通过放置= delete声明后显式禁用默认副本和赋值构造函数的创建.
来自维基百科:
struct NonCopyable {
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable & operator=(const NonCopyable&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
课程也是如此.
使 C++ 对象不可复制的典型方法是显式声明复制构造函数和复制赋值运算符,但不实现它们。这将阻止编译器生成自己的。(通常,这与声明它们一起完成,private以便生成编译错误而不是链接器错误。)
还有boost::noncopyable一个可以继承的类,它执行我上面描述的操作。
C++11 中的良好实践是将复制构造函数和赋值声明为公开删除。不是私下删除,公开删除:https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-delete