2011-07-29 10 views
1

こんにちは私はVS2010とC++でシングルトンパターンを実装しました。コンパイラは私にエラーを投げます!!シングルトンパターンC++エラー

#ifndef __EgEngine__ 
#define __EgEngine__ 1 

#include <esUtil.h> 
#include <stdlib.h> 
#include <EgGpuManager.h> 

class EgEngine 
{ 
public: 
    EgEngine(); 
    static EgGpuManager GetGpuManager(); 
    ~EgEngine(); 
    void EgInit(); 

private: 
    EgEngine(const EgEngine &other){}; 
    EgEngine* operator = (const EgEngine &other)const {}; 
    static EgGpuManager GpuManager; // Return this !! 
    ESContext esContext; 
}; 

#endif 

他のクラス

#ifndef __EgGpuManager__ 
#define __EgGpuManager__ 1 

#include <EgBuffer.h> 
#include <EgProgram.h> 


    class EgGpuManager 
    { 
    public: 
     EgBuffer* GetBuffer(); 
     EgProgram* GetNewProgram(); 

    private: 
     EgGpuManager(); 
     ~EgGpuManager(); 
     EgBuffer buffer; 
    }; 

#endif 

そして私は、私はこのエラーを持ってコンパイルしようとすると:

1>EgEngine.obj : error LNK2001: 
unresolved external symbol "private: static class 
EgGpuManager EgEngine::GpuManager" ([email protected]@@[email protected]@A) 

はしてくださいと感謝私を助けて。

+0

[クラス内の静的メンバー変数]の複製が可能です。(http://www.stackoverflow.com/questions/5601051/static-member-variable-in-a-class) –

+1

[シングルトンを使用しない] //jalf.dk/blog/2010/03/singletons-solving-problems-you-didnt-know-you-never-had-ince-1995/)。彼らはクールではありません。マルチスレッド環境では正しく実装するのは難しく、実装が難しい場合もありますが、正しく実装されている場合でも、コードを悪化させるだけです。 – jalf

+1

また、 '__EgEngine__'のような名前は避けるべきです。二重アンダースコアを含む名前、またはアンダースコアと大文字で始まる名前は、実装(コンパイラと標準ライブラリ)で使用するために予約されています(最後に、マクロをすべて大文字にするのが一般的です) EGENGINE'ではなく、EgEngineである。 – jalf

答えて

4

static EgGpuManager GpuManager; // Return this !!この男はあなたのC++コードのどこかでインスタンス化する必要があります。

staticクラスのメンバーは、C++のファイルに追加して、グローバルスコープに表示されますする必要があります。

EgGpuManager EgEngine::GpuManager

ちなみにEgGpuManagerクラス用のプライベートコンストラクタがありますが、これはEgEngineによって作成されるためこの場合問題になります。シングルトンを正しく実装していません。 static EgGpuManager *EgGpuManager::Get()メソッドを使用してインスタンスを返すと、最初の呼び出しでクラスがインスタンス化されます。次に、専用のコンストラクタでインスタンスを実行できます。それ以外の場合はfriendにします。

+0

ここで、 "EgGpuManager EgEngine :: GpuManager;"を入力する必要があります。 ?? – Eduard

+0

@Eduard - C++ファイルの1つでは、 'EgEngine'クラスの実装を提案します。 – littleadv

+0

私は同じ問題があります。#ifndefの__EgEngine__ の#define __EgEngine__ 1 の#include の#include の#include クラス\t EgEngine {静的EgGpuManager EgEngine :: GpuManager。 公開: \t EgEngine(); \t静的EgGpuManager GetGpuManager(); \t〜EgEngine(); \t void EgInit(); ESContext esContext; プライベート: \t EgEngine(const EgEngine&other){}; \t EgEngine * operator =(const EgEngine&other)const {}; // \t static EgGpuManager GpuManager; }; #endif – Eduard

0

"static EgGpuManager GpuManager;"という行があります。 EgEngineのクラス宣言の内部では、宣言:このオブジェクトはどこかに存在すると言っています。リンカーはオブジェクトをどこにも見つけられなかったと不平を言う。この問題を解決するには、(グローバルスコープで)ソースファイルのいずれかでインスタンス化置く:他の回答により示唆されるようにあなたは、グローバルスコープのいずれかでシングルトンオブジェクトのインスタンスを置く必要があります

EgGpuManager EgEngine::GpuManager; 
0

を、またはこのようなGetGpuManager()の実装で:

EgGpuManager& EgEngine::GetGpuManager() 
{ 
    static EgGpuManager GpuManager; 
    return GpuManager; 
} 

この場合、あなたはクラス定義からGpuManagerの宣言を削除する必要があります。また、オブジェクトのコピーを返すことは望ましくないので(参照:シングルトンを作成する目的を無効にする)、参照を返すように&に注意してください。ここでの利点は、最初にGetGpuManager()が呼び出されるまでオブジェクトが作成されないのに対して、グローバルスコープ内のすべての統計はプログラムの開始時に作成されるという利点があります。

関連する問題