2012-04-01 6 views
2

C++에서 동일한 메소드를 호출하려는 객체가 한 무리 있다고 가정 해보십시오.C++ : 동일한 메소드를 호출하기 위해 객체 반복

하지만 앨리스에서 유유까지 같은 줄을 입력하는 것은 번거로 롭습니다.

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

내가 여기의 for_each 보았다 : 같은 것을 할 수있는 방법이 있나요 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"를 사용하여 원하는 것을 할 수 있습니다. 그건 그렇고, 당신도 functor가 필요합니다.

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(); 

또는 표준에 대한 일반을 사용하여 반복 ::의 for_each를

#include <algorithm> 
#include <functional> 

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

나는 이 경우 n std :: vector. 벡터를 사용하면 초기화 및 반복에 지나치게 자세한 구문을 사용해야하므로 속도가 훨씬 느려집니다.

당신이 훨씬 더 간단한 해결책이있다 그러나 C++ 11을 지원하는 컴파일러가있는 경우 : 이니셜 라이저 목록의 모든 요소가 같은 포인터 타입, Base*이어야한다는

#include <initializer_list> 

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

참고. 그렇지 않은 경우 이니셜 라이저 목록 유형을 명시해야합니다.

// 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(); 
관련 문제