在成员函数中调用析构函数
Calling destructor in member function
如果我们正在实现,例如,智能指针,我们想做 a = std::move(b)
--- 我们需要删除 a
指向的内存,但是我们可以在里面调用析构函数吗移动赋值运算符,而不是复制粘贴析构函数的函数体?
是否定义了在移动赋值中调用析构函数的行为?
如果不是,有没有比复制粘贴析构函数主体更好的处理方法?
您可以在成员函数内调用 this
上的析构函数,它具有 well-defined 行为。
但是,该行为涉及结束对象的生命周期 *this
。在析构函数调用之后,您将不再被允许 access/use 该对象的任何成员。这在许多情况下也会产生不良后果,例如如果对象具有自动存储持续时间,则在作用域退出期间将在其上第二次调用析构函数,这将导致未定义的行为。
所以这对你想做的事情没有用。
尽管我强烈反对它,但理论上您可以通过 placement-new 在同一存储位置构造一个新对象来跟随析构函数调用。但是,有一些先决条件超出了 class 的控制范围,即何时允许这样做而不会导致未定义的行为。在某些情况下,这样的 placement-new 本身可能是未定义的行为,在某些情况下,如果在 placement-new 和在某些情况下,*this
是 subobject/member 的任何父对象的生命周期也将被此类操作结束,如果之后使用会导致未定义的行为。
您可以在标准(草案)中看到关于如何根据我的建议和某些(未说明的)假设实施的演示:https://timsong-cpp.github.io/cppwp/n4868/basic.life#example-2
链接示例和它前面的段落没有详细说明我在上面暗示的方法的所有条件和可能存在的问题。只有示例中显示的 class/function 的非常具体的用法是明确允许的。
如果您只想重用代码,请将析构函数的主体移动到一个新的成员函数中,并从需要相同行为的两个位置调用该函数。
显式调用析构函数在技术上是可行的,您可以在 class Object
.
的非静态方法中使用 this->~Object()
然而,这是一种不好的做法。考虑改用这些。
class Test {
public:
Test() {}
~Test() {
Deallocate();
}
Test(const Test& other) = delete;
Test(Test&& other) {
Deallocate();
// Do sth
}
private:
void Deallocate() {
// Do sth
}
};
如果我们正在实现,例如,智能指针,我们想做 a = std::move(b)
--- 我们需要删除 a
指向的内存,但是我们可以在里面调用析构函数吗移动赋值运算符,而不是复制粘贴析构函数的函数体?
是否定义了在移动赋值中调用析构函数的行为?
如果不是,有没有比复制粘贴析构函数主体更好的处理方法?
您可以在成员函数内调用 this
上的析构函数,它具有 well-defined 行为。
但是,该行为涉及结束对象的生命周期 *this
。在析构函数调用之后,您将不再被允许 access/use 该对象的任何成员。这在许多情况下也会产生不良后果,例如如果对象具有自动存储持续时间,则在作用域退出期间将在其上第二次调用析构函数,这将导致未定义的行为。
所以这对你想做的事情没有用。
尽管我强烈反对它,但理论上您可以通过 placement-new 在同一存储位置构造一个新对象来跟随析构函数调用。但是,有一些先决条件超出了 class 的控制范围,即何时允许这样做而不会导致未定义的行为。在某些情况下,这样的 placement-new 本身可能是未定义的行为,在某些情况下,如果在 placement-new 和在某些情况下,*this
是 subobject/member 的任何父对象的生命周期也将被此类操作结束,如果之后使用会导致未定义的行为。
您可以在标准(草案)中看到关于如何根据我的建议和某些(未说明的)假设实施的演示:https://timsong-cpp.github.io/cppwp/n4868/basic.life#example-2
链接示例和它前面的段落没有详细说明我在上面暗示的方法的所有条件和可能存在的问题。只有示例中显示的 class/function 的非常具体的用法是明确允许的。
如果您只想重用代码,请将析构函数的主体移动到一个新的成员函数中,并从需要相同行为的两个位置调用该函数。
显式调用析构函数在技术上是可行的,您可以在 class Object
.
this->~Object()
然而,这是一种不好的做法。考虑改用这些。
class Test {
public:
Test() {}
~Test() {
Deallocate();
}
Test(const Test& other) = delete;
Test(Test&& other) {
Deallocate();
// Do sth
}
private:
void Deallocate() {
// Do sth
}
};