为了使对象不可复制,我们可以显式删除其复制构造函数和复制赋值运算符。
我的问题是:在课程的public
,private
或protected
部分中,什么地方合适?而且-这种选择有什么区别吗?
答案 0 :(得分:37)
在课程的公共,私人或受保护部分,什么地方合适?
我会将它们放在public
部分。
这是因为删除构造函数或赋值运算符与使它们private
/ protected
正交。而如果不删除它们,则默认情况下为public
。在我看来,将删除内容放在这两个部分之一中,就像是暗示“如果不删除它们,我会将它们设为私有/受保护的”,这不是您要传达的信息。
不过请注意,编译器不在乎将删除内容放入哪个部分。
答案 1 :(得分:21)
我们在其中放置已删除的定义有什么区别吗?
从纯语言的角度来看,它的差值绝对为零。名称检查和重载解析在访问检查之前发生。在重载解析结束时尝试引用已删除的函数会使程序的格式不正确。编译器可能会也可能不会发出有关可访问性的其他诊断,但是程序已经存在必须报告的错误。
因此,您可以根据需要的可访问性来放置已删除的定义。我认为大多数人都将其保持私有状态,以与使类不可复制的“旧”做法保持一致(将那些成员的声明放在类的私有部分中,而不是对其进行定义),如果只是为了帮助那些人。谁知道较早的“获取”旧方法。如果可能的话,混合使用成语。
如果需要同时支持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;
};
答案 2 :(得分:14)
从斯科特·迈耶斯(Scott Meyers)的书《有效的现代C ++》(第10项)看来,最好将它们定义为公开:
按照惯例,已删除的函数被声明为公用,而不是专用。 这是有原因的。当客户端代码尝试使用成员时 函数,C ++在删除状态之前检查可访问性。当客户 代码尝试使用已删除的私有函数,一些编译器抱怨 即使该功能是私有的 可访问性并不会真正影响它是否可以使用。这是值得的 在修订旧版代码以替代时要牢记这一点 私有和未定义成员函数以及已删除的成员函数,因为 公开新功能通常会导致更好的错误 消息。
此外,我认为已删除的副本构造函数/赋值应该是要与所有类用户共享的类接口的一部分。不应通过将此类信息设为私有来将其保密。
答案 3 :(得分:6)
delete
与private
访问权限同样适用。
如果通过重载决策选择函数,delete
的效果是导致错误。
private
的效果是,如果通过来自课堂外或其朋友的重载决议选择该功能,则会导致错误。
如果两个错误都适用,最终结果是相同的,但public
可能有助于避免编译器关于访问权限的消息,这可能会导致混淆。
答案 4 :(得分:2)
delete
d功能的访问无关紧要。事实上,对于类成员,添加额外的访问说明符(delete:
)会更有意义。我怀疑他们没有这样做的原因是,它对非会员职能不起作用。
对于像复制构造函数这样的东西,将它放在public
部分更具风格。一个类没有复制构造函数的事实是了解类的接口的一个非常重要的事实。
对于要将特定重载声明为已删除以便获得错误的编译器时间检测的内部函数,在与所有其他重载相同的部分中声明该函数是有意义的。