应该是不可复制和不可移动的类的一些示例是什么?

时间:2014-02-28 19:03:52

标签: c++ c++11

大多数不可复制的对象都是不可复制的,因为拥有多个不可复制的对象是有意义的或有问题的(例如std::unique_ptr),但移动它们仍然没问题。但是有哪些例子有充分的理由使对象既不可复制也不可移动?

3 个答案:

答案 0 :(得分:5)

当它实现单例模式时。如果只有一个且只有一个类的实例,那么移动或复制它就没有意义。

答案 1 :(得分:1)

std :: condition_variable(见这里:condition_variable)。

我怀疑由于潜在的数据竞争而试图移动。

答案 2 :(得分:1)

在大型软件的代码中,您会发现许多不可复制和/或不可移动的类,但通常缺少不可复制/不可移动的基类。如果您有一个复杂的类引用其他具有引用的对象,则该对象通常被视为不可复制,除非有人提供了执行深度复制的复制构造函数(通过复制引用的对象)。这种情况非常普通,这些复杂的对象通常没有用户指定的复制构造函数。复制/移动构造函数的另一个问题是它们维护是有问题的,它是有人向类添加新成员但却忘记更新复制/移动构造函数的常见错误来源。

但是,在几乎所有情况下,您都可以通过提供自己的复制构造函数来使类复制,除非它在参考图中包含明确标记为不可复制的内容。

什么时候制作不可复制的东西才有意义?在某些情况下,非可复制对象封装了一次只能由一个线程或子系统使用的东西,例如文件句柄或系统资源的任何其他类型的句柄。有时候拥有这样一个资源的副本是没有意义的,但你仍然可以使用移动构造函数将句柄的值安全地移动到另一个地方。

何时制作不可移动的东西?下面是一个示例:假设您为线程间同步创建了一个Lock对象。在Windows上,您可以使用Critical Sections实现此Lock类,并按值将CRITICAL_SECTION放入您的类。 InitializeCriticalSectionhttp://msdn.microsoft.com/en-us/library/windows/desktop/ms683472%28v=vs.85%29.aspx)的文档声明:

  

无法移动或复制关键部分对象。该过程也必须不修改对象,但必须将其视为逻辑上不透明。

因此,将Lock类标记为不可复制且不可移动是明智的。您可以通过仅引用包含CRITICAL_SECTION的对象来使您的Lock类可移动,这样只有当您的Lock实例可移动时,内部对象才不可移动。以这种方式复制Lock实例是不明智的,因为您无法复制CRITiCAL_SECTION实例的内部状态,因此副本在某种程度上与原始实例不同。 / p>

所以总结一下:有时候一个对象因为不受你自己的代码影响的环境(比如CRITICAL_SECTION或一些静态的第三方库)而无法变成可复制的,但是你可以随时使你的类可移动在最坏的情况下,将一些不可移动的成员变量放入由引用保存的内部对象中。实际上,软件中的许多复杂对象都没有不可移动和不可复制的基类,即使它们的复制/移动会导致错误/崩溃。