gpt4 book ai didi

c++ - 自毁:this->MyClass::~MyClass() vs. this->~MyClass()

转载 作者:IT老高 更新时间:2023-10-28 12:44:59 26 4
gpt4 key购买 nike

在学习 C++ 的过程中,我偶然发现了文章 Writing Copy Constructors and Assignment Operators它提出了一种机制来避免复制构造函数和赋值运算符之间的代码重复。

为了总结/复制该链接的内容,建议的机制是:

struct UtilityClass
{
...

UtilityClass(UtilityClass const &rhs)
: data_(new int(*rhs_.data_))
{
// nothing left to do here
}

UtilityClass &operator=(UtilityClass const &rhs)
{
//
// Leaves all the work to the copy constructor.
//

if(this != &rhs)
{
// deconstruct myself
this->UtilityClass::~UtilityClass();

// reconstruct myself by copying from the right hand side.
new(this) UtilityClass(rhs);
}

return *this;
}

...
};

这似乎是避免代码重复同时确保“程序完整性”的好方法,但需要权衡浪费精力释放然后分配嵌套内存的风险,这些内存可以被重用(正如其作者指出的那样) )。

但我不熟悉它的核心语法:

this->UtilityClass::~UtilityClass()

我假设这是一种调用对象的析构函数(销毁对象结构的内容)同时保留结构本身的方法。对于 C++ 新手来说,语法看起来像是对象方法和类方法的奇怪混合。

谁能给我解释一下这个语法,或者给我一个解释它的资源?

该调用与以下调用有何不同?

this->~UtilityClass()

这是一个合法的电话吗?这是否还会破坏对象结构(从堆中释放;从堆栈中弹出)?

最佳答案

TL;DR 版本:请勿听从该链接作者提供的任何建议


该链接表明,只要不使用虚拟析构函数调用,就可以在基类中使用此技术,因为这样做会破坏派生类的某些部分,这不是基类的责任 运算符(operator)=.

这种推理完全失败了。该技术永远不会在基类中使用。原因是 C++ 标准只允许用完全相同类型的另一个对象就地替换一个对象(参见标准的第 3.8 节):

If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:

  • the storage for the new object exactly overlays the storage location which the original object occupied, and
  • the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and
  • the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and
  • the original object was a most derived object (1.8) of type T and the new object is a most derived object of type T (that is, they are not base class subobjects).

在原代码中,return *this; 和后续使用对象都是未定义的行为;他们访问的是已销毁的对象,而不是新创建的对象。

这在实践中也是一个问题:placement-new 调用将设置一个对应于基类的 v-table ptr,而不是对象的正确派生类型。

即使对于叶类(非基类),该技术也存在很大问题。

关于c++ - 自毁:this->MyClass::~MyClass() vs. this->~MyClass(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25365088/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com