在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/ 但是不明白。
答案 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();
}