簡體   English   中英

具有私有構造函數的C ++單例

[英]C++ singleton with private constructor

我需要具有應用程序生存期的單身人士,有保證的創建/銷毀和對它的靜態訪問。

#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。

我習慣於寫單例的方式(無論何時,我真的需要一個):

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

private:
     Singleton()
     {
     }
};

無需搞砸newdelete重載。

您不需要重載new()delete() 而且,您可能不需要向客戶提供指示。 一個參考會做。

單例的構造和銷毀將在您的instance() ,如下所示:

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

這保證了構造和銷毀,因為C的構造函數在第一個用戶調用instance()時被調用,並且僅在第一次調用時被調用。 銷毀將在程序結束時發生。

要刪除的類型為char*

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

您的新產品中有一個錯誤: new char [10]和new char(10)有什么區別?

也許應該是:

p=new char[sz];

接着

delete[] (char*)p ;

----編輯:

純粹主義者的刪除,從而使人們學習時更加清晰;

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

(*實際上,我感謝有關演員表的說明)

在我看來,如果僅刪除newdelete重載,代碼應該可以工作(如果要記錄每個con / destruction,請在con / destructors中這樣做,我並沒有真正意識到這一點),但是下面應該可以解決您的錯誤。

由於您為p分配了char* ,因此應該在delete中將其強制轉換為char* ,即delete (char*)p;

但是,我相信p=new char(sz); 正在創建一個sz值的char,而不是大小為sz的char數組。 對於后者,您可能需要p=new char[sz]; 然后delete[] pdelete[] (char*)p;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM