C ++:遍历对象以调用相同的方法

时间:2012-04-01 01:55:54

标签: c++ oop object foreach iteration

在C ++中,假设您有一大堆对象要调用相同的方法。

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

但是从Alice到Yoyo输入相同的行是很麻烦的。有没有办法做类似的事情:

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

我在这里看到了for_each:http://www.cplusplus.com/reference/algorithm/for_each/ 但是不明白。

4 个答案:

答案 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代替迭代器,无论您喜欢什么。

答案 1 :(得分: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};

并使用普通的for循环迭代它

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

在这种情况下,我不鼓励使用std :: vector。该向量强制您使用过于冗长的语法进行初始化和迭代,并且速度也会慢得多。

如果你有一个支持 C ++ 11 的编译器,那么有一个更简单的解决方案:

#include <initializer_list>

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

请注意,初始值设定项列表中的所有元素必须具有相同的指针类型Base*。如果不是这种情况,则必须明确说明初始化程序列表的类型:

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

答案 2 :(得分:0)

您需要持有“callSameMethod()”的所有对象继承“callSameMethod()”是虚函数的相同接口。所以你可以用“for_each”做你想做的事。顺便说一句,你也需要一个仿函数。

答案 3 :(得分:0)

如果它们是多态的,那么这种事情就可以完成。如果它们都从同一个类继承(如果它们都有共同的方法,它们可能就应该这样),那么你可以将它们全部存储在基类类型的std::vector指针中。然后,只需循环遍历向量并调用此方法即可。

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