2

重複の可能性:
テンプレートをヘッダー ファイルにしか実装できないのはなぜですか?

SOにはこのようなトピックはほとんどないことを認識していますが、私の問題に答えてくれるものは見つかりませんでした.

このチュートリアルhttp://www.codeproject.com/Articles/4750/Singleton-Pattern-A-review-and-analysis-of-existinを使用して、テンプレート シングルトン クラスを既に作成しています。

残念ながら、エラーが発生し続けます:

/home/USER/testcode/cpp_workshop/main.cpp:-1: エラー: `Singleton::Instance()' への未定義の参照:-1: エラー: collect2: ld

私のsingleton.h

#ifndef SINGLETON_H
#define SINGLETON_H

template <typename T>
class Singleton
{
public:
    static T& Instance();

protected:
    virtual ~Singleton();
    inline explicit Singleton();

private:
    static T* _instance;
    static T* CreateInstance();
};

template<typename T>
T* Singleton<T>::_instance = 0;

#endif // SINGLETON_H

シングルトン.cpp

#include "singleton.h"
#include <cstdlib>

template <typename T>
Singleton<T>::Singleton()
{
    assert(Singleton::_instance == 0);
    Singleton::_instance = static_cast<T*>(this);
}

template<typename T>
 T& Singleton<T>::Instance()
{
    if (Singleton::_instance == 0)
    {
        Singleton::_instance = CreateInstance();
    }
    return *(Singleton::_instance);
}

template<typename T>
inline T* Singleton<T>::CreateInstance()
{
    return new T();
}

template<typename T>
Singleton<T>::~Singleton()
{
    if(Singleton::_instance != 0)
    {
        delete Singleton::_instance;
    }
    Singleton::_instance = 0;
}

そして、それが私がそれを呼び出す方法です(通常の場合-テンプレート化されていないか、何もありません-クラスGameSingleton<Game>::Instance().run();

4

3 に答える 3

3

メソッド定義をヘッダーのクラス定義の下に置き、cpp を削除します。テンプレート化されたメソッドとテンプレート化されたクラスのメソッドは、ヘッダーで定義する必要があります (ハック的な例外がいくつかあります)。

リクエストごとに、「ハックの例外」は次のとおりです。

  • 1)@Desmond Humeの回答を参照してください
  • 2) メソッドが定義されている cpp のテンプレート化されたクラスのみを使用します。たとえば、cpp の名前のない名前空間でテンプレート化されたクラスを宣言/定義できますが、それで問題ありません。
于 2012-07-12T13:23:57.793 に答える
2

Singletonクラスの定義をヘッダー ファイルに入れることも、宣言 (ヘッダー) と定義 ( .cppファイル) を分離したままにしておくこともできます。あなたがそれを使用しようとしているタイプ。クラスを明示的にインスタンス化するには、.cpp ファイルの末尾に次の行を追加してみてください。SingletonSingleton

template
class Singleton<Game>;

別のタイプでは、同じように見えます。

template
class Singleton<AnotherGame>; // just for example
于 2012-07-12T13:31:00.237 に答える
0

テンプレート化されたクラスの定義 (ヘッダー ファイル) と実装 (cpp) を分離することはできません。したがって、次の 2 つのソリューションのいずれかが得られます。

1- ヘッダー ファイル .h にすべてを実装します。このようなもの

template <typename T>
class Singleton
{
public:
    static T& Instance(){}

protected:
    virtual ~Singleton(){}
    inline explicit Singleton(){}

private:
    static T* _instance;
    static T* CreateInstance(){}
};

別の解決策は、.cpp クラスの名前を .hpp に変更することです。.hpp ファイル内に .h ファイルを含めないでください。つまり、.h ファイル内に .hpp ファイルを含めます。

私は個人的に最初の解決策を好みます

乾杯

于 2012-07-12T13:29:41.843 に答える