【问题标题】:destructor is never called析构函数永远不会被调用
【发布时间】:2010-08-03 09:57:46
【问题描述】:

对不起,我的疏忽,简而言之~CSArray() 是有效的,但是类的接口和实现在不同的文件中,所以这里是错误

【问题讨论】:

  • 您确定保留/释放计数匹配吗?
  • 保留计数实际上是否达到零? CSObject 的析构函数被调用了吗? CSObject的析构函数是虚拟的吗?
  • 来自调试器,“保留计数实际上是否达到零?”是 'CSObject 的析构函数被调用了吗?是 'CSObject 的析构函数是虚拟的吗?是的,没有调用 CSArray 的析构函数
  • 您知道获得好的答案的最佳方法是发布可重现错误的可编译代码。但是缺少看起来 CSObject 的析构函数不是虚拟的或者 self 没有指向正确的东西(什么是 self?)。
  • 能看到CSObject的析构函数的声明和定义吗?我的钱仍然在那个不是虚拟的。此外,您将delete this 更改为delete self。 self 是什么?

标签: c++


【解决方案1】:

确保在基类中声明了析构函数virtual。

【讨论】:

  • virtual,仅调用 CSObject 析构函数,
【解决方案2】:

目前显示的代码太短,看不出问题。

一些好的建议:永远不要建立自己的引用计数方案。使用经过验证的库实现,如 std::auto_ptr、boost::shared_ptr 或 boost::shared_array 并利用 RAII (http://en.wikipedia.org/wiki/RAII)。 另外,避免像瘟疫一样“删除这个”。它在某些情况下似乎可行,但通常前置/后置条件太多了。

【讨论】:

  • 在尝试引用计数之前研究delete this; 上的条件是一个好主意,但是引用计数既不复杂也不困难,正如大量 COM 组件所证明的那样,所有这些组件都实现了 @987654324 @。此外,您建议的类不是线程安全的,因此“重用库版本”可能会带来很多麻烦。
  • @Ben:OP 的代码是线程安全的吗?另见stackoverflow.com/questions/692438/…
  • Markus,我喜欢 Cocoa 风格的,所以我制作了它们
【解决方案3】:

假设_retainCount = 0

只要你在基类中声明了你的析构函数virtual,它就可以工作。

见以下代码:(gcc 版本 3.4.3)

#include<iostream>
using namespace std;

class A
{
    public:
        A(){cout<<"A ctor"<<endl;};
        virtual ~A(){cout<<"A dtor"<<endl;};
        void testDel()
        {
            delete this;
        }
};

class B: public A
{
    public:
        B(){cout<<"B ctor"<<endl;};
        ~B(){cout<<"B dtor"<<endl;};
};

int main()
{
    B bObj;

    bObj.testDel(); 
   return 0; 
}

结果:没有显式删除

A ctor
B ctor
B dtor
A dtor

结果:显式删除

A ctor
B ctor
B dtor
A dtor
B dtor
A dtor

【讨论】:

  • 我不太清楚你所说的“完美运行”是什么意思;删除自动变量会产生未定义的行为,并且很可能会崩溃,就像你得到的双重破坏一样。
  • @Mike Seymour 我只是为了证明调用了析构函数。好吧,我应该删除“完美”这个词:) ...我没有考虑这里的 UB ...
猜你喜欢
  • 2013-08-31
  • 1970-01-01
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-30
  • 2017-12-17
  • 2018-09-02
相关资源
最近更新 更多