C++ 类之间的函数指针

C++ 类之间的函数指针,c++,member-function-pointers,C++,Member Function Pointers,我很难理解如何将类成员函数传递给子类(不是派生的) 我的顶级课程是这样的: class CTop { public: CTop(); int func1(void); private: CFnList* _funcList; }; CTop::CTop(): _funcList(0) { _funcList = new CFnList(); _funcList->addFnPtrToList(0, &CTop::func1); }

我很难理解如何将类成员函数传递给子类(不是派生的)

我的顶级课程是这样的:

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;
};
int (CTop::*fn)(void)
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});
}
我的函数列表类如下所示:

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;
};
int (CTop::*fn)(void)
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});
}
类CFnList
{
公众:
//公共职能
CFnList();
void addFnPtrToList(int索引,int(*fn)(void));
私人:
//指针列表
类型定义结构
{
整数指数;
int(*fn)(无效);
}fn\u列表\u t;
//函数指针列表
QVector(QVector)fn(QVector)列表;;
};
基本上这里我有一个类CTop的实例,它的一个成员是指向类CFnList的指针。CFnList指针在CTop的构造函数中实例化。然后我想通过调用以下行将指向CTop成员函数之一的指针传递给CFnList: _funcList->addFnPtrToList(0,&CTop::func1) 我(非常正确地)发现addFnPtrToList不接受参数(int,(CTop::*)())。因此编译器知道这个函数是一个特定的成员函数,而不仅仅是一个泛型(可能是静态)函数

是否有方法将指向成员函数的指针传递到子类中?在我的例子中,我希望子类能够调用这个函数。我在想,我可能必须创建静态成员函数之类的东西,但语法让我无法理解如何做到这一点

感谢所有的帮助/建议。
Fodder是一个成员函数<代码>&CTop::func1不是函数指针,而是指向成员(函数)的指针。无论是在存储还是调用中都不能混合使用。它与
int(*fn)(void)
不兼容,因为后者不接受参数,而前者需要一个作为隐藏
this
传递的对象


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

以下格式的声明:

int (*fn)(void)
无法指向成员函数。它只能指向一个自由函数。通常,这是因为成员函数的调用约定与自由函数的调用约定不同。例如,考虑在成员函数调用的上下文中需要<代码>此< /Cult>指针。

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

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;
};
int (CTop::*fn)(void)
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});
}

在专用于成员函数指针的部分中有一整节。查看它。

您正在传递成员函数,就像它是一个常规函数一样。未能包含对类的“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);

这是最终的解决方案,它混合使用传递对象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...
}
类CTop
{
公众:
CTop();
int func1(无效);
私人:
CFnList*_funcList;
};
CTop::CTop():
_功能列表(0)
{
_funcList=新的CFnList(此);
_funcList->addFnPtrToList(0,&CTop::func1);
}
int CTop::func1(无效)
{
//做一些事情。。。
}
我的函数列表类如下所示:

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;
};
int (CTop::*fn)(void)
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});
}
模板
类CFnList
{
公众:
//公共职能
CFnList(T*母公司);
void addFnPtrToList(int索引,int(T::*fn)(void));
私人:
//指向父级(或所有者可能更正确)的指针
T*_父母;
//指针列表
类型定义结构
{
整数指数;
内部(T::*fn)(无效);
}fn\u列表\u t;
//函数指针列表
QVector(QVector)fn(QVector)列表;;
};
//建造师
模板
CFnList::CFnList(T*父项):
_家长(家长),
_fn_列表(0)
{
}
//addFnPtrToList:
模板
void CFnList::addFnPtrToList(int索引,int(T::*fn)(void))
{
_追加((fn_list_t){index,fn});
}
因此,主要的变化是: 1.通过将CFnList更改为模板来传递CTop类型。 2.通过将“this”传递到构造函数中,然后模板类将其存储为指向给定模板类型的指针,从而传入对象CTop的实例(以便调用指向函数的指针)…vio la!…简单:o


感谢所有贡献者:)

对于我方回复缓慢表示歉意,我已经没有时间了。我的一天就要结束了:(感谢您的评论:)我理解您突出显示的所有选项(+1)除了“成对的PTM+对象指针”。那是什么。。。听起来我可以通过传递对象和成员(函数)来做我想做的事情。。。类似这样的东西?是的,如果您有指向成员pFn的指针和指向实例pTop的指针,那么您可以发出
(pTop->*pFn)(ARGS)
进行实际调用。存储固定类型和签名的配对并不难。不错的帖子+1:)。。。在我的例子中,我有不止一个“CTop”类型的类想要使用CFnList类,所以明确地告诉它对象类型对我来说不是一个真正的选项:(FAQ看起来不错,我一定会在早上读到这篇文章!因为这是最后的工作方式…忘记选择答案:)谢谢你的帖子。好主意+1:),但我有类似的问题与约翰的职位以上。我不能显式地使用对象类型,因为在我的代码中有许多类似于“CTop”的类,它们希望使用CFnList来存储指向其函数的指针。一个潜在的解决方案是让所有这些类继承一个公共基类并使用函数重载。这样列表维护者就可以维护对CTopInheritedClass PTR的引用。这就是我所能想到的。无论哪种方式,你都必须保持一个p