2016-07-21 6 views
1

これはC++で新しく、削除についてはlinkです。シングルトンパターンを実装したコードがあります。私はこのコードをテストしている:テスト時の問題「新規のシングルトンと削除(C++)」

#include <iostream> 
#include <memory> 

class Singleton { 
    static Singleton *instance; 
    static std::size_t refcount; 
    std::string _s; 

    public: 
    void setS(std::string s) { _s = s; } 
    std::string getS() { return _s; } 
    static void *operator new(std::size_t nbytes) throw (std::bad_alloc) { 
     std::cout << "operator new" << std::endl; 
     if (instance == nullptr) { 
      std::cout << "operator new nullptr" << std::endl; 
      instance = ::new Singleton; // Use the default allocator 
     } 
     refcount++; 
     return instance; 
    } 

    static void operator delete(void *p) { 
     std::cout << "operator delete" << std::endl; 
     if (--refcount == 0) { 
      std::cout << "operator delete" << refcount << std::endl; 
      ::delete instance; 
      instance = nullptr; 
     } 
    } 
}; 

Singleton *Singleton::instance = nullptr; 
std::size_t Singleton::refcount = 0; 

int main() { 
    Singleton* s = new Singleton; 
    //Singleton* t = new Singleton; 
    s->setS("string s"); 
    std::cout << "s " << s->getS() << std::endl; 
    Singleton* t = new Singleton; 
    std::cout << "t " << t->getS() << std::endl; 
    return 0; 
} 

をしかし、結果は次のとおりです。

operator new 
operator new nullptr 
s string s 
operator new 
t 

なぜtは、 "文字列s" をプリントアウトしませんでしたか?コメント行を変更すると、「文字列s」が表示されます。

+0

'* s == * t'とは何ですか? – user4759923

+0

スタックに割り当てられたインスタンスはどのように考慮されますか? – user2672165

+0

@ user4759923:* sと* tは全く同じで、1つだけです。しかし、シングルトンには演算子==はありません。この演算子を定義すると、結果はあなたに依存します。 – aviit

答えて

2

ステートメントnew Singletonは、operator newを呼び出してストレージを取得し、デフォルトのコンストラクターを使用してオブジェクトの非静的メンバーを初期化します。

_sは静的ではないため、新しいSingletonが作成されるたびに(再)初期化されます。その結果、tの空白文字列になります。

この方法で_sメンバーのスペースを再利用する可能性は非常に高いです。

+0

記憶域は同じですが、すべての非静的メンバーを(再)初期化するnew式ごとにコンストラクタが呼び出されます。 – aviit