复制构造函数、析构函数和赋值运算符。我们什么时候不需要它们呢?
我知道 C++ 的经验法则,当您将 cctor、dtor 或 op= 添加到您的类中时,您还需要添加其他两个以使您的类在所有情况下都能正常工作。
是否存在不需要提供全部三项,只提供其中一两个的情况?
如果您将其中之一添加到您的类中,为什么 C++ 不要求您将它们全部添加?
EDIT1:
您提到了一些示例,您不仅不需要其中一些,而且不想拥有它们,因此您希望将它们设为私有或受保护。但即使主体是空的,您仍然需要将它们写入代码中。
当您通过添加具有空体的虚拟析构函数来使类多态时,我没有拥有它们的唯一有效原因。但是,一旦您在析构函数的主体中编写了一些内容,您就应该考虑在 cctor 和 op= 的主体中也编写一些内容。
我正在寻找不需要编写所有 3 个方法的示例,并且即使新手正在使用您的类,您也可以省略其中一些方法,而不会在您的类中引起错误。 :)
I know the C++ rule of thumb when you add cctor, dtor or op= to your class, you need to add the other two too to make you class work properly under all circumstances.
Are there any case when you don't need to provide all the three, just one or two of them?
Why don't the C++ require you to add them all if you add one of them to your class?
EDIT1:
You mentioned examples when you not only don't need some of them, but you don't want to have them so you want to make them private or protected. But you still need to write them in your code even with empty bodies.
The only valid reason for me not having them all when you make a class polimorphic by adding a virtual destructor with empty body. But as soon as you write something in the destructor's body, you should consider writing something in the body of the cctor and op= too.
I'm looking for examples when you don't need to write all 3 methods and you can omit some of them without causing bugs in your class even if a newbie are using your class. :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可能希望使用不带复制构造函数或赋值运算符的析构函数的一种情况是在开发多态类时,在这种情况下您希望虚拟析构函数允许通过基类指针进行释放。这些类通常支持复制构造函数,以促进“虚拟克隆”习惯用法。然而,它们很少有赋值运算符,因为多态类通常是堆分配的并且仅通过指针引用,在这种情况下直接赋值几乎总是会导致切片。
One case in which you may want to use a destructor without a copy constructor or assignment operator is when developing a polymorphic class, in which case you want a
virtual
destructor to allow deallocation through a base class pointer. These classes often will support copy constructors in order to facilitate the "virtual clone" idiom. However, they rarely have assignment operators, since polymorphic classes are usually heap-allocated and referenced only through pointers, in which case direct assignment almost always leads to slicing.观察类(向另一个类报告其生命周期的类)需要所有构造函数和析构函数,但不需要 op=。 C++ 不需要它们,因为它完全没有必要——我们程序员最了解。
此外,如果您有一个不可复制的类,您可能需要析构函数而不是其他两个。
Observed classes (those that report their lifetimes to another class) require all constructors and destructor, but not op=. C++ doesn't require them because it would be completely unnecessary- we, the programmers, know best.
In addition, you may want destructor but not the other two if you have a non-copyable class.
如果类中有指针或类似的东西,则必须将它们全部写入,这样在复制 cctor 或 op= 中就不会出现浅复制,并且在 dtor 中不会出现内存泄漏。
这是您应该将它们全部写出的一种情况,其他情况存在于其他答案中。
C++ 并不需要所有这些,因为它编写了默认的,并且因为它们可能不是必需的。
You have to write them all if you have pointers or sth like that in your class so there will be no shallow copy in the copy cctor or op=, and no memory leak in dtor.
This is one case where you should write them all, other cases exist in other answers.
C++ doesn't require them all because it writes default ones, and because they may not be neseccary.
一般来说,当您想要更改访问权限时,或者在以下情况下
析构函数,使其成为虚拟的。声明私有复制构造函数
或赋值运算符是禁止这些操作的经典方法,
即使你不需要析构函数;任何时候你想从中获得
一个类,析构函数应该是虚拟的(或受保护的);如果你
想要禁止除了动态分配的实例之外的任何东西,经典的
习惯用法是将析构函数声明为私有,并实现一个析构函数
函数会
delete this
来删除该对象。最后,编译器生成的版本是内联的,您可能想要
声明这些函数之一以防止其内联。 (在
内存较小的日子里,这通常是一个考虑因素。)
Generally, when you want to change the access rights, or in the case of
the destructor, make it virtual. Declaring a private copy constructor
or assignment operator is a classical way of banning these operations,
even if you don't need a destructor; any time you want to derive from
a class, the destructor should be virtual (or protected); and if you
want to forbid anything but dynamically allocated instances, the classic
idiom is to declare the destructor private, and implement a destruct
function which does
delete this
to get rid of the object.Finally, the compiler generated versions are inline, and you might want
to declare one of these functions to prevent it from being inline. (In
days of smaller memory, this was often a consideration.)