0

我很难弄清楚如何将类成员函数传递给子类(不是派生的)。

我的顶级课程是这样的:

class CTop
{
public:
    CTop();
    int func1(void);

private:
    CFnList* _funcList;
};

CTop::CTop():
    _funcList(0)
{
    _funcList = new CFnList();
    _funcList->addFnPtrToList(0, &CTop::func1);
}

int CTop::func1(void)
{
    // Does some stuff...
}

我的函数列表类是这样的:

class CFnList
{
public:
    // Public functions
    CFnList();
    void addFnPtrToList(int index, int (*fn)(void));

private:
    // Fn pointer list
    typedef struct
    {
        int index;
        int (*fn) (void);
    }fn_list_t;

    // function pointer list
    QVector<fn_list_t> _fn_list;
};

所以基本上在这里我有一个类 CT​​op 的实例,它的一个成员是一个指向类 CFnList 的指针。CFnList 指针在 CTop 的构造函数中实例化。然后我想通过调用以下行将指向 CTop 的成员函数之一的指针传递给 CFnList:“_funcList->addFnPtrToList(0, &CTop::func1);” 我得到的问题(非常正确) addFnPtrToList 不采用参数(int,(CTop::*)())。所以编译器知道这个函数是一个特定的成员函数,而不仅仅是一个通用(可能是静态的)函数。

有没有办法将指向成员函数的指针传递给子类?就我而言,我希望子类能够调用此函数。我在想我可能必须制作静态成员函数或其他东西,但语法让我无法理解如何做到这一点。

所有帮助/建议表示赞赏。饲料

4

4 回答 4

4

CTop::func1是成员函数。&CTop::func1不是函数指针,它是指向成员(函数)的指针。这些在存储或调用中都不能混合。它与 不兼容 int (*fn)(void),因为后者不带参数,而前者需要一个作为隐藏对象传递的对象this

由于这些原因,您不能拥有一个简单但统一的设施。您可以使用简单的函数指针,或成对的 PTM+对象指针,或者使用包装器——手工制作或库存boost::function,如boost::bind. 如果你有 C++11 或 TR1,你可以使用后者的 std:: 等价物。

于 2013-06-11T15:39:50.210 回答
3

形式的声明:

int (*fn)(void)

不能指向成员函数。它只能指向一个自由函数。从哲学上讲,这是因为成员函数的调用约定与自由函数的调用约定不同。例如,考虑this在成员函数调用的上下文中需要指针。

声明指向成员函数的指针的语法如下:

int (CTop::*fn)(void)

C++ FAQ中有一个完整的部分专门讨论成员函数指针。一探究竟。

于 2013-06-11T15:41:13.123 回答
1

您正在传递成员函数,就好像它是常规函数一样。这不包括对类的“this”引用。为了传递成员函数,您必须能够从原始“this”中重新引用它。请看以下内容。

typedef void (CTop::*OBJFNC)(args);

_funcList = new CFnList();
_funcList->addFnPtrToList(0, this, &CTop::func1);


void addFnPtrToList(int index, CTop* pobj, OBJFNC pfnc)
{ ... Store both ...
}

现在在其他地方您可以使用以下命令执行它。

(pobj->*pfnc)(args);
于 2013-06-11T15:44:18.900 回答
0

这是最终的解决方案,它混合了传递对象 CTop 的实例和使用 CFnList 的模板类:

我的顶级类是这样的(或多或少相同,除了 _funcList 的声明以包含类类型并将“this”传递给构造函数:

class CTop
{
public:
    CTop();
    int func1(void);

private:
    CFnList<CTop>* _funcList;
};

CTop::CTop():
    _funcList(0)
{
    _funcList = new CFnList(this);
    _funcList->addFnPtrToList(0, &CTop::func1);
}

int CTop::func1(void)
{
    // Does some stuff...
}

我的函数列表类是这样的:

template<class T>
class CFnList
{
public:
    // Public functions
    CFnList(T *parent);
    void addFnPtrToList(int index, int (T::*fn)(void));

private:
    // Pointer to the parent (or owner is perhaps more correct)
    T* _parent;

    // Fn pointer list
    typedef struct
    {
        int index;
        int (T::*fn) (void);
    }fn_list_t;

    // function pointer list
    QVector<fn_list_t> _fn_list;
};

// Constructor
template <class T>
CFnList<T>::CFnList(T *parent) :
    _parent(parent),
    _fn_list(0)
{
}

// addFnPtrToList:
template <class T>
void CFnList<T>::addFnPtrToList(int index, int (T::*fn)(void))
{
    _fn_list.append((fn_list_t){index, fn});
}

所以主要的变化是: 1. 通过将 CFnList 更改为模板来传递 CTop 类型。2. 通过将“this”传递给构造函数,传入对象 CTop 的实例(以便可以调用指向函数的指针),然后模板类将其存储为指向给定模板类型的指针.... vio-拉!...容易:o

感谢所有贡献的人:))

于 2013-06-12T12:01:10.037 回答