说我有课:
class A
{
public:
void doSomething();
}
doSomething在哪里做了明确依赖于A实例的内部状态的东西。
现在,我有一种情况,我有很多类型A的东西,但我只想从它们的一个严格的子集中调用doSomething,所以我想把它们粘在列表上。特别是,我真正想做的是将指针粘贴到列表中的单个doSomethings()。
我可以这样做吗?我是否声明它:
std::list<(A::*)()> aDoSomethings;
我读了this entry,这是有道理的,如果需要,我会走那条路。
答案 0 :(得分:3)
您是否考虑过简单的面向对象方法:
struct Can_Do_Something
{
virtual void doSomething() = 0;
};
class A : public Can_Do_Something
{
...
};
std::list<Can_Do_Something*> my_list;
my_list[n]->doSomething();
这限制性地保持对您计划通过列表访问的A接口部分(通过Can_Do_Something类型继承)的访问。它记录并执行该限制。
如果您偏好更接近原始愿景的事物,请考虑......
#include <iostream>
#include <vector>
#include <boost/function.hpp>
struct A
{
A(int n) : n_(n) { }
int f(int x) { std::cout << "A::f() this " << (void*)this
<< ", n_ " << n_
<< ", x_ " << x << '\n'; }
int n_;
};
int main()
{
typedef boost::function<int (int n)> Function;
typedef std::vector<Function> Functions;
Functions functions;
A a1(1), a2(2), a3(3);
functions.push_back(std::bind1st(std::mem_fun(&A::f), &a1));
functions.push_back(std::bind1st(std::mem_fun(&A::f), &a2));
functions.push_back(std::bind1st(std::mem_fun(&A::f), &a3));
for (Functions::iterator i = functions.begin();
i != functions.end();
++i)
(*i)(42);
}
这里,boost :: function用于创建对您感兴趣的特定函数的回调。
答案 1 :(得分:2)
您似乎对成员函数指针的工作原理感到困惑。对于给定的类,任何给定函数只有一个实例。它们通过使用隐式参数this
来区分。基本上,您可以假装您有以下映射。
struct Struct { void Function(); }
Struct a;
a.Function();
变成
struct Struct { }
void Function(Struct* this);
Struct a;
Function(&a);
因此,如果您有一堆Struct
个对象,并且想要在其中一小部分上调用Function
,则不存储Function
,而是存储{{1} }}
当您有多个功能时,会使用指向成员函数的指针,您需要选择性地调用它们。因此,如果您的类中有两个函数,它们都没有参数并返回void,Struct
可以指向它们中的任何一个。但它仍然指向一个特定的功能,其中只有一个。您仍需要提供void (Struct::*)()
参数。
this
不是最好的例子,但它得到了重点。您可以使用成员函数混合和匹配对象。
*编辑:没有容器阻碍的示例
struct Struct {
Struct(int v) : value(v) { }
void One() { cout << "one: " << value << endl; }
void Two() { cout << "two: " << value << endl; }
int value;
};
int main()
{
std::vector<Struct> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
std::vector<void (Struct::*)()> f;
f.push_back(&Struct::One);
f.push_back(&Struct::Two);
f.push_back(&Struct::One);
for(int i = 0; i < 3; ++i)
(v[i].*f[i])();
}
请注意额外的括号。 Struct a(5), b(10);
void (Struct::*one)() = &Struct::One;
void (Struct::*two)() = &Struct::Two;
(a.*one)();
(b.*one)();
(a.*two)();
(b.*two)();
不足。
答案 2 :(得分:1)
成员函数指针没有指向特定实例的指针:它描述了如何使用this
指针和参数调用具有特定签名的成员函数。
相反,将指向您关注的对象的指针放入列表中,然后遍历该列表,在每个项目上调用doSomething
。
答案 3 :(得分:1)
你应该检查一下boost :: function和boost :: bind。
答案 4 :(得分:0)
是的,你可能想要这样的东西:
#include <vector>
#include <iostream>
#include <string>
using namespace std;
class A {
string m_name;
public:
A(const string& name) : m_name(name) {}
void doSomething() { cout << m_name << "::doSomething()" << endl; }
};
int main(void) {
A f1("f1");
A f2("f2");
A f3("f3");
A f4("f4");
vector<A*> foo_list;
foo_list.push_back(&f1);
foo_list.push_back(&f3);
for (vector<A*>::iterator it = foo_list.begin(); it != foo_list.end(); *it++) {
static_cast<A*>(*it)->doSomething();
}
return 0;
}
答案 5 :(得分:0)
如果我的理解是正确的,你想要一个指向函数成员的指针列表必须是doSomething()吗?
然后你可以有一个指向你的类成员的函数指针列表,但你需要提供相关的对象,那么为什么不简单地保留一个(指向)对象的列表呢?