单例类的析构函数被调用两次!

时间:2011-07-04 10:01:49

标签: c++

我的代码如下:

    class Singleton {
        private:
        int i;
        static bool stnflag;
        static Singleton* single;
        Singleton(int a)
        {
            i=a;
        }
        public:
        static Singleton* getinstance(int);
        void function();
        ~Singleton()
        {
          cout << "destructor is being called" << endl;
          stnflag=false;
        }
};

bool Singleton::stnflag=false;
Singleton* Singleton::single=NULL;
Singleton* Singleton::getinstance(int a)
{
        if(!stnflag)
        {
          single = new Singleton(a);
          stnflag=true;
          return single;
        }
        else
        {
                cout << "already single object created" << endl;
                return single;
        }
}

void Singleton::function()
{

cout << "private member value in single ton class is :" << i << endl;
}

int main()
{
        Singleton *s1,*s2;
        s1=Singleton::getinstance(3);
        s1->function();
        s2=Singleton::getinstance(4);
        s2->function();
        delete s1;
        delete s2;
        return 0;
}

当调用delete s2时,析构函数也被第二次调用!!但是怎么可能呢?已经删除s1 ri8中删除了对象的指针。但是我在析构函数中获取了第二个删除s2的print语句..可以任何人给出原因..但是根据我的假设,它会因为错误而错过双自由指针ri8 !!

5 个答案:

答案 0 :(得分:12)

好吧,不要再打电话给delete两次!

在已删除的对象上调用delete未定义的行为,而不是保证崩溃。

您应该考虑让getinstance()返回引用,而不是指针。

答案 1 :(得分:4)

s1和s2指向同一个对象。您在该对象Undefined Behavior上调用两次删除。删除一个对象并没有真正做任何魔术 - 它只是标记它占用的内存可以自由重用。所以不要指望如果你删除它,它会消失或者某种东西......

答案 2 :(得分:2)

问题是未定义的行为。

你是对的,这是一个双倍免费,但双重免费的结果不能保证。有时你会崩溃,或者在其他时候它似乎默默地“工作”。这种事情的结果是不可预测的,并且取决于程序外部的一系列因素。

不要被这个误导:双重免费仍然是错误的!

答案 3 :(得分:0)

当您使用getInstance时,您应该拥有returnInstance,而不是称之为“删除”明确,因为您不会调用“新”。当你调用getInstance时,你需要一个会增加的引用计数;

e.g。

Siggleton::getInstance()
{
   instances++;
   ....
}

void Singleton::returninstance()
{
        instances--;
        if(instances == 0 && signle != null)
        {
            delete single;
            single = null;
            stnflag = false;
        }
}

答案 4 :(得分:0)