1

次のように実装されたシングルトンクラスがあります。

#include <iostream>
using namespace std;

template<class T>
class singleton{
protected:
    static T* s_instance;
public:
    T* instance(){
        if(s_instance){
            return s_instance ;
        }else{
           s_instance = new T;
           return s_instance;
        }
    }
};
template <class T>
T* singleton<T>::s_instance;

class A:public singleton<A>{
    friend class singleton;
public:
  void print_add(){
    cout<<"I AM A"<<endl;
    cout<<s_instance<<endl;
  }
  ~A(){
      //delete s_instance;
      cout<<"Dest A"<<endl;
   }
private:
    A(){}
};

class B:public singleton<B>{
    friend class singleton;
public:
  void print_add(){
    cout<<"I AM B"<<endl;
    cout<<s_instance<<endl;
 }
 ~B(){
       cout<<"Dest B"<<endl;
       //delete s_instance;
  }
private:
    B(){}
};

int main(){
    A* a, *c;
    B* b;
    a->instance()->print_add();
    b->instance()->print_add();
    c->instance()->print_add();     
}

このために destruct-or を呼び出す方法。上記の「削除」行がないと、valgrind はメモリ リークが 0 であるように見えます。ポインターを削除せずに、メモリをリークしていますか? またはシングルトンの実装方法が間違っていますか?これら 2 つのクラスには、共通の静的メンバーがあります。基本的に、ここでオブジェクトごとに静的メンバーがどのように異なるのですか?

ありがとう

4

2 に答える 2

2

注目すべき点がいくつかあります。

実際には、メモリ リークは発生していません。クラスのインスタンスは 1 つしか作成できず (つまり、リークによってリソースが過剰に使用されることはありません)、そのインスタンスに割り当てられたメモリは、クライアント プロセスの終了時に OS によって取り除かれます。

OS によってリープされるのではなく、プログラムの終了時にシングルトン インスタンスが確実に削除されるようにする最も簡単な方法は、関数スコープを持つ静的インスタンスを使用することです。

template<class T>
struct Singleton {
  static T& instance() {
    static T instance_;
    return instance_;
  }
};

class SingletonClient : public Singleton<SingletonClient> {
  friend class Singleton<SingletonClient>;

  SingletonClient()
  {}
};

SingletonClient &s = Singleton<SingletonClient>::instance();

テンプレートを使用してシングルトンを実装するには、いくつかの微妙な点があります。複数の翻訳単位でシ​​ングルトン テンプレートのインスタンス化を使用すると、実際にはシングルトン クライアントのインスタンスが 1 つだけ必要な場合でも、実際には複数のインスタンスが作成される可能性があります。これに対処する方法は、クライアント クラスのヘッダー ファイルで extern テンプレート宣言を使用し、クライアントの実装ファイルでテンプレートのインスタンス化を使用することです。

// In header file of SingletonClient:
extern template class Singleton<SingletonClient>;

// In the implementation file of SingletonClient:
template class Singleton<SingletonClient>;
于 2013-08-03T17:26:11.867 に答える