删除复制和复制 - 公共,私人或受保护?

问题描述 投票:32回答:5

为了使对象不可复制,我们可以显式删除其copy-constructor和copy-assignment操作符。

我的问题是:什么是正确的地方 - 在课堂上的qazxsw poi,qazxsw poi或qazxsw poi部分?而且 - 这个选择有什么不同吗?

c++ c++11 access-modifiers deleted-functions
5个回答
38
投票

什么是正确的地方 - 在班级的公共,私人或受保护的部分?

我会把它们放在public部分。

这是因为删除构造函数或赋值运算符与使它们private / protected正交;当这些没有删除时,默认情况下它们是public。将删除放在这两个部分中的一个似乎在暗示“如果我没有删除它们,我会将它们设为私有/受保护” - 这不是您希望在您的情况下传达的消息。

但请注意,编译器并不关心将删除的部分放在哪个部分。


20
投票

我们把删除的定义放在哪里有什么区别?

从纯粹的语言角度来看,它绝对是零差异。在访问检查之前发生名称查找和重载解析。并且在重载决策结束时尝试引用已删除的函数会使您的程序格式错误。编译器可能会或可能不会发出有关可访问性的其他诊断信息,但程序已经出现了必须报告的错误。

因此,您可以将删除的定义与您想要的任何可访问性放在一起。我认为大多数人都会把它保密,以便与使用不可复制的类的“旧”做法内联(将这些成员的声明放在类的私有部分,而不是定义它们),如果只是为了帮助那些谁知道旧的方式“早点”得到它。如果你愿意,可以混合成语。

如果您需要同时支持C ++ 03和C ++ 11模式,那么标记为私有也是您无法避免的。在宏的帮助下,可以使标题容易符合这两个标准:

private

14
投票

从Scott Meyers的书“Effective Modern C ++”(第10项)开始,似乎将它们定义为公共更好:

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

另外,我认为删除的复制构造函数/赋值应该是要与所有类用户共享的类接口的一部分。不应将这类信息作为私密信息保密。


6
投票

protectedpublic访问同样适用。

如果通过重载决策选择函数,#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; }; 的效果是导致错误。

delete的效果是如果函数是通过类或其朋友之外的重载决策选择的,则会导致错误。

如果两个错误都适用,那么最终结果都是相同的,但是private可能有助于避免有关访问权限的编译器消息,这可能会导致混淆。


2
投票

访问deleted函数是无关紧要的。实际上,对于类成员来说,添加额外的访问说明符(private)会更有意义。我怀疑他们没有这样做的原因是,它不适用于非会员职能。

对于像复制构造函数这样的东西,将它放在public部分更具风格。一个类没有复制构造函数的事实是了解类的接口的一个非常重要的事实。

对于要将特定重载声明为已删除以便获得错误的编译器时间检测的内部函数,在与所有其他重载相同的部分中声明该函数是有意义的。

© www.soinside.com 2019 - 2024. All rights reserved.