2012-04-01 33 views
2

C++では、同じメソッドを呼び出すオブジェクトがたくさんあるとします。C++:オブジェクトを繰り返して同じメソッドを呼び出す

Alice->callSameMethod(); 
Bob->callSameMethod(); 
... 
Yoyo->callSameMethod(); 

しかし、アリスからヨーヨーまで同じ行を入力するのは面倒です。私はこっちfor_each見

For (each x in {Alice,Bob, ..., Yoyo}) x->callSameMethod; 

http://www.cplusplus.com/reference/algorithm/for_each/ が、それを理解していなかったような何かをするが方法です。

+0

配列または標準ライブラリコンテナでこれらのオブジェクトはありますか? – Blastfurnace

+3

もしそうでなければ、それらを作ってください:) –

+0

そして、それらは同じタイプまたはベースタイプですか? –

答えて

5

例:

どこかあなたのコード内
class Base{public: virtual int callSameMethod() = 0;}; 
      //pure virtual, can make it a default implementation 
class Alice: public Base {public: int callSameMethod();...}; // own implementation 
class Bob: public Base {public: int callSameMethod();...}; // own implementation 
class YoYo: public Base{public: int callSameMethod();...}; // own implementation 

:これは "多型" と呼ばれている

Base* p1 = new Alice(); 
Base* p2 = new Bob(); 

std::vector<Base*> v; 
std::vector<Base*>::iterator it; 
v.push_back(p1); 
v.push_back(p2); 
for (it = v.begin(); it != v.end(); it++) (*it)->callSameMethod(); 

、およびお使いのベースクラスは、共通のインタフェースを定義することにより、どんな種類の派生品かを正確に知らなくても、それを呼び出すことができます。単純なループの代わりにstd::for_eachを使用するか、イテレータの代わりにインデックス付きのアクセスを使用してvectorを使用することができます。

0

「callSameMethod()」が仮想関数であるのと同じインターフェイスを継承するには、「callSameMethod()」を保持するすべてのオブジェクトが必要です。だからあなたは "for_each"を使ってあなたが望むことをすることができます。ちなみに、ファンクタも必要です。

0

多態性であれば、このようなことが可能です。それらのクラスがすべて同じクラスから継承されている場合(おそらく共通のメソッドがあれば)、すべてを基本クラス型のポインタのstd::vectorに格納できます。次に、単にベクトルをループしてこのメ​​ソッドを呼び出すだけです。

すなわち

for (std::vector<BaseClass*>::iterator it = objectsVec.begin(); 
             it != objectsVec.end(); 
             ++it) 
{ 
    (*it)->callSameMethod(); 
} 
1

すべてのオブジェクトは、共通の基本タイプまたは同じタイプのものでなければなりません。

class Base { public: virtual void callSameMethod() = 0; }; // abstract base 
class Derived1 : public Base { public: virtual void callSameMethod() {:::}; }; 
class Derived2 : public Base { public: virtual void callSameMethod() {:::}; }; 

// instances 
Base* Alice = new Derived1; 
Base* Bob = new Derived2; 
Base* YoYo = new Derived1; 

この場合、最も洗練されたソリューションは、使用しているC++のバージョンによって異なります。

C++ 03であなたはすべての要素へのポインタを含んでいるコンテナを作成することができます

Base* const list[] = {Alice, Bob, YoYo}; 

とループ

int length = (sizeof(list)/sizeof(Base*)); 
for(int i = 0; i < length; ++i) list[i]->callSameMethod(); 

またはSTDのための通常のを使用して、それを反復:: for_eachを

#include <algorithm> 
#include <functional> 

std::for_each(list, list + length, std::mem_fun(&Base::callSameMethod)); 

私は使用をお勧めしません。この場合はn std :: vectorとなります。このベクトルは、初期化と反復のために過度に冗長な構文を使用するよう強制しますが、非常に遅くなります。初期化子リスト内のすべての要素が同じポインタ型、Base*でなければなりません

#include <initializer_list> 

for (auto i : {Alice, Bob, YoYo}) i->callSameMethod(); 

注:C++ 11をサポートしてコンパイラを使用している場合は

は、しかし、はるかに簡単な解決策があります。そうでない場合は、初期化子リストのタイプが明示的に指定する必要があります。

// alternative declarations with different pointer types 
Derived1* Alice = new Derived1; 
Derived2* Bob = new Derived2; 
Derived1* YoYo = new Derived1; 

auto objects = std::initializer_list<Base*>{Alice, Bob, YoYo}; 
for (auto i : objects) i->callSameMethod(); 
関連する問題