【问题标题】:Validity of "this" in destructor析构函数中“this”的有效性
【发布时间】:2014-10-27 15:33:42
【问题描述】:

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

"object destroyed at %p", this

我担心this 在这种情况下的定义有多好。

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

【问题讨论】:

  • 当它从析构函数返回时会被销毁,所以它应该仍然有效
  • 应该还是?如果我介绍 UB,我会遇到很多麻烦。
  • 有效,你可以自己测试一下
  • 在我的平台上确实可以。我可以同时测试i = ++i。但这根本不是定义行为的指南。
  • 这取决于析构函数是否为non-trivial,参见相关:stackoverflow.com/questions/8611468/…。在普通析构函数的情况下,当您从析构函数返回时,对象的生命周期结束。如果一进入body就发生了,那么你将无法释放成员资源

标签: c++


【解决方案1】:

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

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

【讨论】:

  • +1,这里的核心问题是指针是否还有有意义的值,而不是是否可以解引用。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      所以您的代码格式正确。所有非静态数据成员和基类的析构函数在析构函数体执行完毕后被调用。

      【讨论】:

        【解决方案5】:

        在析构函数内部,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
        }
        

        【讨论】:

          猜你喜欢
          • 2021-09-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-19
          • 2014-10-19
          • 2016-10-12
          • 2021-12-08
          • 2015-07-27
          相关资源
          最近更新 更多