Notice : 内容無保証。禁無断転載。リンク自由。

singleton_1.cpp

#include <stdio.h>

// デザインパターン - Singleton - _instance をメンバにした、デストラクトに問題のある例

//

class Singleton {
private:
    static Singleton*  _instance ;
    int*               m_pi ;

protected:
    // コピー抑止
    Singleton(Singleton& s){}
    Singleton& operator=(Singleton& s){return *this;}

    // クラス外でのコンストラクト抑止
    Singleton(){
        printf("Singleton コンストラクト\n") ;
        m_pi = new int(0) ;
    }

public:
    ~Singleton(){
        delete m_pi ;
        m_pi = 0 ;
        printf("Singleton デストラクト\n") ;
    }

    static Singleton* Instance() ;

    int i(void) const {return *m_pi ;}
    int i(int x) {*m_pi = x ; return x ;}
} ;

//  Singletonクラスの実装

Singleton* Singleton::_instance = 0 ;

Singleton* Singleton::Instance() {
    if (_instance == 0) {
        _instance = new Singleton ;    // 一つだけ生成して、ずっと消さないつもり。
    }

    return _instance ;
}

// 使用

static void set(int i){
    Singleton::Instance()->i(i) ;
}

static int get(void){
    return Singleton::Instance()->i() ;
}

int main(void){
    set(10) ;
    printf("%d\n", get()) ;

    delete Singleton::Instance() ; // #! デストラクタがpublicなので、外から勝手に消せてしまう。

    try{
        printf("%d\n", get()) ;   // Singleton::_instance はすでにデストラクトされているので、例外発生。
    }catch(...){
        printf("bad Singleton::instance.\n") ;
    }

    return 0 ;
}