2009-06-26 32 views
0

一般的なvarを作成したいと思います。これは1つのクラスまたは別のクラスから作成できます。私は、クラスAまたはクラスBの一般的なvar C++

からコードにアクセスすることができます。しかしaaはGLOBALでなければなりません私のコードでのように、VARのaaは、一般的なことが、私が欲しいこのサンプルコードで

お手伝いできますか?

class MyClass 
{ 
public: 
    MyClass() {} //contructor padrão, não deve ser utilizado isoladamente 

    static MyClass* getInstance() 
    { 
     static MyClass *instance = 0; 
     if (!instance) instance = new MyClass(); 
      return instance; 
    } 
}; 

class A : public MyClass 
{ 
public: 
    int a() { return 1; } 
}; 

class B : public MyClass 
{ 
public: 
    int b() { return 1; } 
}; 

template <class TAIT> class AIT 
{ 
public: 
    static TAIT& Instance() 
    { 
     static TAIT instance; 
     return instance; 
    } 
}; 

AIT aa; 

void main() 
{ 
    aa.Instance().a(); // or 
    aa.Instance().b(); // aa could be class 
         // A or class B. So I could access 
         // function a or function b (not at same 
         // time, of course) 

    return; 
} 
+1

私はあなたが求めているものを理解していません。してくださいそれをより明確にするようにしてください。 – CiscoIPPhone

+1

私はどちらかそれを得ることはありません。おそらく、あなたはあなたの現在の問題をより明確にしてみてください。いずれの場合も、上記のコードで問題がたくさんありますが、実際の質問せずに私が開始する場所さえわからないんだけど... –

答えて

1

基本クラスに純粋な仮想を宣言し、それを派生クラスでオーバーロードします。

class MyClass { 
public: 
    virtual int a() = 0; 
}; 

class DerivedA : public MyClass { 
public: 
    virtual int a() { return 1; } 
}; 

どちらの派生クラスは、同じ名前のメソッドを持って、あなたは、オブジェクトの種類に応じて呼び出すためにどの方法を自動的に解決されます。作成するクラスインスタンスを知るには、GetInstance()メソッドの作成部分を書き直す必要があります。

2

私が正しくあなたを理解していれば、私はあなただけ正しくaaを宣言する必要があると思うし、あなたが設定している:

AIT<A> aa; 
aa.Instance().a(); 

AIT<B> bb; 
bb.Instance().b(); 

それはあなたが何を意味するかでない場合は、あなたの質問を編集して、何を明確にしてくださいあなたがしようとしている。

7

短い答え:

C++テンプレートを使用すると、コンパイル時に汎用性、汎用性を実行時ではない与えます。

テンプレート自体は、プログラム内には存在しません(具体的なバイナリ実行可能ファイル)。引数を明示的または暗黙的に指定することによってインスタンス化された場合にのみ生成コードとして終了します。これは、変数を宣言

AIT aa; 

だから、これは変数を宣言しない

:あなたは、ランタイム・汎用性が必要な場合は、実行時のディスパッチメカニズムを使用する必要が

AIT<A> aa; 

  • スイッチケースを使用して手動で行うか、
  • 以上は、共通の基底クラス+いくつかの仮想メソッドの組み込み継承を使用してください。
0

getInstanceメソッド以外からコンストラクタを呼び出さないようにするには、非公開にすることができます。例えばあなたのコンストラクタは、これがこの問題に適したソリューションです

0

プライベートなので

class MyClass 
{ 
private: 
    MyClass() {} //contructor padrão, não deve ser utilizado isoladamente 
public: 
    static MyClass* getInstance() 
    { 
     static MyClass *instance = 0; 
     if (!instance) instance = new MyClass(); 
      return instance; 
    } 
}; 

は今

MyClass* a = new MyClass(); 

は、コンパイルエラーが発生するのでしょうか?

クラスのMyClass {パブリック: MyClassの(){} //デフォルトコンストラクタ単独 仮想INT(使用すべきではない)= 0。仮想int型B()= 0;

int c()   {   return b();   } 

    static MyClass* getInstance() 
    { 
     static MyClass *instance = 0; //   if (!instance) instance 

のMyClass =新しいです();インスタンスを返す 。 }}。

クラス:公共MyClassの{パブリック: INT(){1を返します。 int型B}(){リターン1 。 }のInt D(){リターン1。 }}。

Bクラス:公共MyClassの{パブリック: INT(){1を返します。 int型B}(){リターン1 。 }であり、INT(){1を返します。 }}。

クラスC:公共、公共B {パブリック: CA。 BのCB。

TYPE列挙{A、B}。 TYPEタイプ。

C(タイプtype){タイプ=タイプ。 }

INT(){スイッチ(タイプ){ケース A:戻りca.a()。破ります; ケースB:戻りcb.b()。破ります; デフォルト:休憩; }}}

ボイドメイン(){// * A = MyClassのMyClassの::のgetInstance(); // MyClassの* B = のMyClass ::のgetInstance();

C C(C :: B)。 C.A();
aa.Instance //()(); aa.Instance //()B(。)。

リターン。 }

0

それは間違いなく厄介だが、おそらくここに解決策は、ボイドポインタを使用することです。ボイド*にCとC++のポインタでは何も定義された型を持っていないと宣言されています。あなたの周りのこのポインタを渡した後、あなたが望むものは何でも、データ型のポインタにキャストすることができます。明らかに慎重にそれが実際に正しい型の変数であることを確認するために非常に重要ですが、あなたは、あなたが戻り値の型を知らないインタフェースを設計している場合、これは便利です。ここでは、クラスがインタフェースをどのように見えるかの例です:

class InterfaceClass { 
    public: 
    virtual void* someInterface() = 0; 
} 

あなたは次にインターフェイスを実装し、必要面白いものは何でも物事ない別のクラスQUEを作成することができます。

class DerivedClass: public InterfaceClass { 
    public: 
    virtual void* someInterface() { 
     //do some stuff 
     return (void*) somePointer; 

}

長いですあなたがする必要がある任意のコードは、あなたが欲しいポインタのどんなタイプのバック渡すことができるものを理解しています。あなたがvoidポインタをGoogleを検索する場合より多くの情報がたくさんあります。注意してください。