2012-02-19 4 views
0

私はこれが可能だとは思っていませんが、質問する価値があります:私は静的なものの内部から非静的なメンバー関数を呼びたいと思います。私はクラスのすべての現在のインスタンスのためにそれをしたいと思います。出来ますか? 「オブジェクトなしのメンバ関数を呼び出すことはできません 『無効TestClassをを:: NonStaticMethod()』」C++で静的メンバーメソッドの内部で非静的メンバーメソッドを呼び出すことは可能ですか?

+3

をうまくいくかのアイデアを与えるためにしようとしていますか?これはどんなクラスですか?「すべてのインスタンスを追跡する」ことについて話を始めると、どれだけの柔軟性が失われるのか考えましたか?私は、長年の専門的経験に基づいて、あなたがそのような決定を後悔するようになることを事実上保証することができます。 –

+0

アドバイスをいただきありがとうございます。私は新しいプログラマーであり、実際にはこれはおそらく私が望むことをするための最良の方法ではありません。しかし、私はまだそれが可能かどうかを知りたい。 – Anthony

答えて

5

あなたはいくつかのトリッキーでそれを行うことができます。 すべてのインスタンスを追跡する場合は、クラス構築時にインスタンスを登録する必要があります。もちろんこれは、権利を取得するのが難しいですが、ここでは大まかなアプローチがあります:

class Foo 
{ 
    static std::unordered_set<Foo*> instances; 

    void do_it(); // non-static member function 

public: 
    Foo() 
    { 
     instances.insert(this); 
     // ... 
    } 

    // add copy constructor, move constructor, etc. 

    ~Foo() 
    { 
     instances.erase(this); 
     // ... 
    } 

    static void call_all() 
    { 
     for (Foo * p : instances) { p->do_it(); } 
    } 
}; 

あなたはすべてコンストラクタは登録を行っていることを確認する必要があります。

+0

新しいプログラマで失われることの多い点を説明するために、そのアクセスは 'this'ポインタではなくタイプによって制御されます。' do_it'をprivateにすることをお勧めします。 –

+0

暗黙的に生成されたコピーコンストラクタも処理する必要があります。コピーコンストラクタを削除するか、オブジェクトを登録するかのどちらかです。私は、複数のコンストラクタを持つことによる干渉を最小限に抑え、それに対処することを忘れることを避けるために、登録ロジックをメンバーまたはベースに因数分解すると思います。 –

+0

@BenVoigt:インスタンスごとではなく、クラスごとにアクセスするという意味ですか?うーん、おそらく...それは良い点だ。 –

1

はい、あなたが呼び出すことができます。

私はテストクラスでこれをしようとすると、私は次のエラーを取得します静的メンバーの中から非静的メンバーを削除することができます。

o.member(); 

または

p->member(); 

同じことが非静的メンバ変数にアクセスするために行く:

あなたは非静的メンバ関数が適用されるにインスタンスを提供する必要があります

o.var++; 
p->var++; 

クラスのすべてのインスタンスでそれを行う限り、何とかリストを保持するのはあなた次第です。

+2

OPはすべての現在のインスタンス*に対してコール*を行いたいと考えています。 –

+0

静的メソッドを呼び出すときには「現在のインスタンス」はありません。 –

+0

@KerrekSB:ええ、私は答えを書いた後でそれを見て、あなたがコメントしたときに編集プロセスに入っていました。なぜ人々は質問に正確なタイトルをつけることができないのですか? –

0

静的でない関数を正当に呼び出すことができるのは、関数を呼び出すオブジェクトがある場合だけです。静的関数にthisが含まれていないので、instanceMethod();、さらにはMyClass::instanceMethod();と言うことはできません。何とかあなたはobj.instanceMethod();またはobjPtr->instanceMethod();と言う必要があります。

静的関数内からクラスのオブジェクトを作成する(または取得することもできます)場合は、好きなように呼び出すことができます。 C++では、デフォルトでは、作成したオブジェクトの種類や場所を知ることはできませんので、自分で追跡する必要があります。 1つの方法は、コンストラクタに追加してデストラクタから削除するオブジェクトの静的なリスト/配列/マップ/セット/オブジェクトを持つことです。

1

静的ではないメソッドを直接呼び出すことはできませんが、現在のインスタンスごとに何かを実行したい場合は、静的なインスタンスのリストを維持し、このリストを反復することによって行うことができます。あなたのクラスのコンストラクタは、この静的リストに自身を追加することができ、デストラクタは自身を削除することができます。

1

さて、少し微調整できます。基本的には、クラスのすべてのインスタンスをコンストラクタに格納します。今はC++を覚えていないので、以下のコードはうまくいきません。私はちょうどあなたがそのような何かをしたいと思うのはなぜ

class someClass{ 
static someClass instances[50]; 
static int count=0; 

void dosomething(){ 

} 

void someClass(){ 
//Constructor 
someClass::instances[someClass::count++]=this;//Store the instance 
} 

static int theBoss(){ 
//This is the static method that calls the non static member. 
int ctr=0; 
while(ctr<count){       
instances[ctr++].dosomething();Iterate over the instances and call their non static method 
} 
} 
+0

C++の文字通りの数字は '0'、' 1'と '-1'ですが、' 50'は決してありません:-S –

+0

は学校からC++を使ったことがなく、ターボ3.x版しか学んでいませんでした。それ以来変化してきた –

0
#include <iostream> 

class A { 
public: 
    void foo(){std::cerr << "foo\n";} 
    static void bar(A &a){ a.foo(); } 
    void bar1(){bar(*this); } 
}; 

int main(int argc, char *argv[]) 
{ 
    A a; 
    A b; 
    A::bar(a); 
    A::bar(b); 
    //OR 
    a.bar1(); 
    b.bar1(); 
return 0; 
} 
関連する問題