删除版权副本和版权转让-是公共的,私人的还是受保护的?

Saj*_*jal 32 c++ access-modifiers deleted-functions c++11

为了使对象不可复制,我们可以显式删除其复制构造函数和复制分配运算符。

我的问题是:什么是做正确的地方-在publicprivateprotected之类的部分?并且-这种选择有什么区别吗?

ein*_*ica 38

在班级的公共,私人或受保护区域中,这样做的正确位置是什么?

我将它们放在该public部分中

这是因为删除构造函数或赋值运算符与使它们private/ 正交protected。如果不删除它们,则public默认情况下为它们。在我看来,将删除内容放在这两个部分之一中似乎暗示着“如果不删除它们,我会将它们设为私有/受保护的”,这并不是您要传达的信息。

但是请注意,编译器不在乎将删除内容放入哪个部分。

  • 就是这个 过去,我们专门将这些东西私有化,以阻止人们访问它们,但是_这始终是黑客行为,并且**仅**,因为我们无法“删除”它们。这种考虑不再起作用。我不记得“复制构造函数是私有的”诊断是否倾向于优先于“复制构造函数被删除”的诊断(我对此表示怀疑),但是即使它没有更改访问级别也不是正确的选择因为你给的原因 (8认同)

Sto*_*ica 20

将删除的定义放在何处有什么不同?

从纯语言的角度来看,它的差值绝对为零。名称检查和重载解析在访问检查之前发生。在重载解析结束时尝试引用已删除的函数会使程序的格式不正确。编译器可能会(也可能不会)发出有关可访问性的其他诊断,但是程序已存在必须报告的错误。

因此,您可以将删除的定义与所需的任何可访问性一起放入。我认为大多数人都将其保持私有状态,以与使类不可复制的“旧”做法保持一致(将那些成员的声明放在类的私有部分中,而不是对其进行定义),如果只是为了帮助那些人。谁知道较早的“获取”旧方法。如果可能的话,混合使用成语。

如果需要同时支持C ++ 03和C ++ 11模式,则也不能避免将其标记为私有。借助宏,可以轻松地使标头符合两个标准:

#if __cplusplus >= 201103L
  #define DELETED_DEFINITION = delete
#else
  #define DELETED_DEFINITION
#endif

class noncopyable {
private:
  // This header can be compiled as both C++11 and C++03
  noncopyable(noncopyable const&) DELETED_DEFINITION;
  void operator=(noncopyable const&) DELETED_DEFINITION;
};
Run Code Online (Sandbox Code Playgroud)

  • @LightnessRacesinOrbit 如果您想要向后兼容,则永远不要使用 C++11 功能。在删除函数的情况下,StoryTeller 提出了解决方法。但是在使用 lambdas、stl、并发等时的向后兼容性解决方案是什么? (2认同)
  • @hsalimi到目前为止,如果您想要一个有用的兼容层,那么您只能使用 C++11 功能,这是真的,但我在之前的项目中确实有一个事件框架库,可以用 C++03 或 C+ 进行编译+11 模式(遗留嵌入式项目仍然使用它),在后一种情况下,它进行了一系列优化(主要与右值引用相关),这些优化极大地改进了事情,而不会太严重地破坏界面。我确实需要它在 Boost.Thread 和 `std::thread` 之间切换,但在后一种情况下,它减轻了库(和链接!)依赖性,所以它不是徒劳的。 (2认同)

Gup*_*pta 14

从斯科特·迈耶斯(Scott Meyers)的著作《有效的现代C ++》(第10项)看来,最好将它们定义为public

按照惯例,已删除的函数被声明为公共的,而不是私有的。这是有原因的。当客户端代码尝试使用成员函数时,C ++会在删除状态之前检查可访问性。当客户端代码尝试使用已删除的私有函数时,即使函数的可访问性并没有真正影响它是否可以使用,某些编译器只会抱怨该函数是私有的。修改旧版代码以用已删除的私有和未定义成员函数替换旧代码时,请牢记这一点,因为公开新函数通常会产生更好的错误消息。

另外,我认为删除的副本构造函数/赋值应该是要与所有类用户共享的类接口的一部分。不应通过将此类信息设为私有来将其保密。

  • Meyers与StoryTeller的回答和[我的测试](http://coliru.stacked-crooked.com/a/9515319644f041db)相矛盾。仍然是很好的建议,但我发现einpoklum的推理要好。 (2认同)

Pot*_*ter 6

deleteprivate访问同样有效。

delete如果通过重载分辨率选择功能,则会导致错误。

private如果通过重载解析从类或其朋友外部选择函数,则的结果将导致错误。

如果两种错误均适用,则最终结果是相同的,但public可能有助于避免有关访问权限的编译器消息,这可能会引起混乱。