-1

我已经阅读了几篇关于此的帖子,但似乎无法通过示例代码找到我正在寻找的内容,如果有人能给我一些帮助,我将不胜感激。

在我的标题中,我有:

void addEvent(void (*func)(Pack  *));

void triggerEvents(Pack * );

std::list<void(*)(Pack *)> eventList;

并在 cpp 文件中

void DNetwork::addEvent(void (*func)(Pack *)){
    eventList.push_back(func);
}

void DNetwork::triggerEvents(Pack * pack){
    for (std::list<void (*)( Pack *)>::iterator it = eventList.begin(); it !=         eventList.end() ;it++ ){
        (*it)(pack);
    } 
}

这适用于免费函数,但是当我尝试将成员函数添加到此列表时出现错误。有谁知道如何在指针中存储成员函数(来自随机类对象)?

4

4 回答 4

3

简单的解决方案是在函数/函数指针类型上使用类型擦除,更简单的方法是使用std::function<>

std::list<std::function<void (Pack*)>;

function然后,您可以使用自由函数或成员函数(通过std::bind将成员函数与要调用它的对象绑定)甚至函数对象(提供 的类型)来初始化对象operator()

于 2013-06-25T18:31:50.173 回答
1

对于成员函数,您需要绑定。成员函数是具有其类的隐式参数的“普通函数”。所以你需要一个活页夹。如果你使用 c++11,你可以使用 std::bind 和 std::function 或者你可以对非 c++11 代码使用 boost::bind 和 boost::function。

typedef std::function< void ( Pack* ) > MyFunction;
void addEvent( MyFunction f );
void triggerEvents( Pack* );
std::list< MyFunction > eventList;

void DNetwork::addEvent( MyFunction f )
{
    eventList.push_back( f );
}

void DNetwork::triggerEvents( Pack *pack )
{
    for ( auto it = eventList.begin(); it != eventList.end(); it++ )
    {
        (*it)(pack);
    } 
}

现在,如果我有 A 类的方法,doA( Pack* )我会写:

A a;
Pack pack;
DNetwork d;
d.addEvent( std::bind( &A::doA, &a, &pack ) );

或者更好的是你可以使用 Boost.Signal 或者你可以使用发布者/订阅者模式

编辑 @DavidRodríguez-dribeas 建议:绑定不应采用 &pack 参数,因为成员函数的参数是在 triggerEvents 的调用位置提供的。正确的方法是:

A a;
Pack pack;
DNetwork d;
d.addEvent( std::bind( &A::doA, &a, std::placeholders::_1 ) );
d.triggerEvents( &pack );
于 2013-06-25T18:43:29.690 回答
-1

你可以做一个重载,例如:

std::list<void(*)(Pack *)> eventList;
void addEvent(void (*func)(Pack  *));
template<typename T>
void addEvent(void (T::*func)(Pack  *));
namespace Abstraction {
    template<typename T>
    void abstractlyAddEvent( T, std::list<void(*)(Pack *)> *eventList );
}
于 2013-06-25T18:49:00.600 回答
-2

如果我理解您的问题,当您尝试将函数添加到 addEvent 中的列表时会出现错误?

如果要添加指向类的非静态成员函数的指针,请确保它具有正确的语法……例如,指向 TestClass 中成员函数的函数指针如下所示:

void * (TestClass:: *) ()
于 2013-06-25T18:26:48.427 回答