1

我需要具有应用程序生命周期的单例,保证创建/销毁和对其的静态访问。

#include <iostream>
#include <cstdlib>

#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
    TypeName(const TypeName&);             \
    void operator=(const TypeName&)

#define M() C::sM()
#define M2() C::sM2()

using namespace std;

class C {
  private:
    static C* s;

    ~C() { cout << "~C()" << endl; }
    static C* instance() { 
        if (s==NULL) { s=new C(); }
        cout << "instance()=" << s << endl; return s; 
    }
    static void cleanUp() { delete s; }
    void m() { cout << "m()" << endl; }
    void m2() { cout << "m2()" << endl; }
    DISALLOW_COPY_AND_ASSIGN(C);
  public:
    C() { 
        cout << "C()" << endl; if (s==NULL) { 
            s=this; atexit(&cleanUp); 
            cout << "cleanUp is installed" << endl; 
        } else { 
            cout << "cleanUp is not installed" << endl; 
        } 
    }
    void* operator new(size_t sz) { 
        void* p=NULL; if (s==NULL) { p=new char[sz]; } else { p=s; }
        cout << "new(" << sz << ")=" << p << endl;
        return p;
    }
    void operator delete(void* p, size_t sz) { 
        cout << "delete(" << sz << "," << p << ")" << endl;
        if (p) delete[] static_cast<char*>(p); s=NULL; 
    }
    void static sM() { cout << "sM()" << endl; instance()->m(); }
    void static sM2() { cout << "sM2()" << endl; instance()->m2(); }
};

C* C::s = NULL;

int main() {
    M();
    M2();
    C* p1 = new C();
    C* p2 = new C();
}  

但我不知道如何摆脱 g++ 警告:

test.cpp: In static member function 'static void C::operator delete(void*, size_t)':
test.cpp:22: warning: deleting 'void*' is undefined

如果我写 C* 而不是 void*,析构函数开始在无限循环中调用自己。任何人都可以帮助我在没有警告的情况下获得干净的代码吗?当然是 C++98。

4

4 回答 4

4

我用来写单例的方式(当我真的需要时)是:

class Singleton
{
public:
     static Singleton& instance()
     {
          static Singleton theInstance;
          return theInstance;
     }

private:
     Singleton()
     {
     }
};

无需搞乱重载newdelete.

于 2013-09-04T12:33:43.700 回答
2

您不需要重载既new()也不重载delete()。而且您可能不需要向您的客户分发指针。一个参考就可以了。

单例的构造和销毁将在您的 中完成instance(),如下所示:

static C& instance() {
  static C _instance;
  cout << "instance()" << endl; 
  return _instance; 
}

这保证了构造和销毁,因为 C 的构造函数在第一个用户调用时调用instance(),并且仅在第一次调用时调用。销毁将在您的程序结束时发生。

于 2013-09-04T12:40:36.213 回答
0

要删除的类型是char*

void operator delete(void* p, size_t sz) { 
    cout << "delete(" << sz << "," << p << ")" << endl;
    if (p) delete (char*) p;
}

您的 new 中有一个错误:new char[10] 和 new char(10) 之间有什么区别

也许应该是:

p=new char[sz];

接着

delete[] (char*)p ;

----编辑:

纯粹主义者的删除,牺牲了人们学习的清晰度;P:

delete[] static_cast<char*>(p) ;

(*其实我很欣赏关于演员表的说明)

于 2013-09-04T12:38:13.470 回答
0

在我看来,如果您仅删除newanddelete重载,您的代码应该可以工作(我真的不明白这一点,如果您想记录每个 con/destructions,请在 con/destructors 中这样做),但是下面应该解决您的错误。

由于您将 a 分配char*p,因此将其强制转换char*为 delete 应该可以工作,即delete (char*)p;.

但是,我相信p=new char(sz);正在制作一个 char 值sz而不是 size 的 char 数组sz。对于后者,您可能需要p=new char[sz];and then delete[] por delete[] (char*)p;

于 2013-09-04T12:38:18.703 回答