析构函数中"this"的有效性

Validity of "this" in destructor

本文关键字:有效性 this 析构函数      更新时间:2023-10-16

在析构函数的最后一行,我有一条诊断类型消息,它采用类似printf的形式:

"object destroyed at %p", this

然而,我担心this在这样一个点上的定义有多好。

我应该有这样的保留吗?行为是否定义明确?

根据C++标准(12.4析构函数)

8在执行析构函数的主体并销毁任何在body内分配的自动对象,类的析构函数X调用X的直接非变量非静态数据的析构函数成员,X的直接基类的析构函数,如果X是派生类(12.6.2)的类型,其析构函数调用X的虚拟基类的析构函数。

因此,您的代码格式良好。所有非静态数据成员和基类的析构函数都是在执行析构函数体之后调用的。

好吧,指针本身肯定仍然存在(毕竟它只是一个地址)。打印指针值应该没有问题。

另一方面,你在析构函数中所做的一切都已经发生了。属性可能已经是delete'd等,所以您必须避免任何访问这些属性的操作。

这具有定义良好的行为。考虑一下,this指针可以在整个析构函数中隐式或显式使用,例如,每当您访问像delete ptr_;这样的成员变量时析构函数返回后,成员将按照声明/创建的相反顺序销毁,然后调用基析构函数。

现在,您可以从析构函数访问类成员。如果this指针无效,这将不起作用。因此,您可以放心地假设this指向的地址仍然与您在构造函数中打印的地址相同。

在析构函数内部,this指针以及所有成员和基都定义得很好(析构函数返回后,将以构造相反的顺序销毁)。所以打印它所指的地址不是UB。

唯一的问题是,对象本身不能再被认为是"多态的",因为派生的组件已经被破坏。

class A
{
public:
    virtual void fn() { std::cout << "A::fn" << std::endl; }
    virtual ~A() { fn(); } //< will call A::fn(), even if B is destroying
};
class B: public A
{
public:
    virtual void fn() { std::cout << "B::fn" << std::endl; }
    virtual ~B() {}    
};
int main()
{
    B b;
    A& a = b;
    a.fn(); //< will print B::fn(), being A::fn virtual and being B the runtime-type of the a's referred object
    return 0; //< will print A::fn() from b's A's component destructor
}