1

次のコードがあります

#include <vector>
#include <iostream>

class A{
    private:
    std::vector<int> x;
    A(){
        // here is a code to open and initialize several devices
        // it is allowed to be called once only!!!
        std::cout << "constructor called" << std::endl;
    };

    virtual ~A(){
        // here is a code to close several devices
        // it is allowed to be called once only!!!
        std::cout << "destructor called" << std::endl;
    };


    public:
    static A & getA(){
        static A* singleton = new A;
        std::cout << "singleton got" << std::endl;
        return *singleton;
    };

};


int main(int argc, char** argv){

    A a = A::getA();

    return(0);
}

多くの推奨事項によると、デストラクタはプライベートであり、プログラムの最後に一度だけ呼び出されます。
しかし、私はコンパイラエラーがあります:

Test.cpp: In function 'int main(int, char**)':
Test.cpp:12:10: error: 'virtual A::~A()' is private
Test.cpp:29:19: error: within this context
Test.cpp:12:10: error: 'virtual A::~A()' is private
Test.cpp:29:19: error: within this context

当然のことながら、コンストラクタやデストラクタを公開することができ、そのようなエラーは発生しません。ただし、両方が一度だけ呼び出されるようにする必要があります。
どのように?

4

3 に答える 3

4

あなたのプログラムにはいくつかのものがあります:

  1. コピー コンストラクターの実装がありません
  2. シングルトンオブジェクトをコピーしています
  3. デストラクタはプライベートです(シングルトンオブジェクトをコピーしているため、パブリックセクションにデストラクタが必要です)

オブジェクトをコピーしないことで簡単に解決できます。

int main(int argc, char** argv){

    A &a = A::getA();
}

シングルトンは単一のインスタンスのままにする必要があるため、(提案されているように) 最善の方法は、コピー コンストラクターと移動コンストラクターを削除することです。


コンストラクタとデストラクタは 1 回だけ呼び出す必要があるため、 meyers singletonを使用する必要があります。これは、関数を次のように変更することを意味します。

static A & getA(){
   static A singleton;
   std::cout << "singleton got" << std::endl;
   return singleton;

};

于 2012-10-24T06:33:10.907 に答える
1

とてもとてもシンプルです。デストラクタを非公開にしないでください!

唯一のコンストラクターをプライベートにすることで、クラスがシングルトンであることを保証します。デストラクタもプライベートにする必要はありません。

于 2012-10-24T06:30:49.043 に答える
0

シングルトン コンストラクターのこのメソッドを使用することをお勧めします。

static A* getA(){
    static A singleton;
    std::cout << "singleton got" << std::endl;
    return &singleton;
};

詳細情報へのリンクはこちら

于 2012-10-24T06:34:47.990 に答える