游戏开发论坛

 找回密码
 立即注册
搜索
楼主: 微无渊

怎么在类中使用成员函数指针?

[复制链接]

0

主题

12

帖子

32

积分

注册会员

Rank: 2

积分
32
发表于 2013-4-13 15:26:57 | 显示全部楼层
class Test
{
public:
        void f(int i)
        {
                cout << "i==" << i <<endl;
        }
};
typedef void (Test::*pFunc)(int);
int main()
{
        Test t;
        pFunc pf = &Test::f;
        (t.*pf)(10);
}这样子可以,因为这是类的成员函数指针,所以必须得知道调用哪个实例的函数,因此必须得有该实例的起始地址。

0

主题

12

帖子

32

积分

注册会员

Rank: 2

积分
32
发表于 2013-4-13 15:32:23 | 显示全部楼层
但是得注意的是,上面的pFunc只能是这个类的,如果其他类也有相同返回类型而且参数个数和类型一样,也就是说有个Test2这样的一个类,也有void f(int i)这样的一个函数,如果想通过成员函数指针来调用Test2实例的那个函数,就必须得再次typedef void (Test2::*pFunc2)(int);
不过这样做了重复工作,你可以通过类的模板来避免这个重复工作,相关的技术有C++委托,百度一下就可以找到该技术的类库。

50

主题

236

帖子

454

积分

中级会员

Rank: 3Rank: 3

积分
454
 楼主| 发表于 2013-4-17 14:47:05 | 显示全部楼层
楼上没搞清楚我问的是什么

0

主题

12

帖子

32

积分

注册会员

Rank: 2

积分
32
发表于 2013-4-18 12:53:12 | 显示全部楼层
我已经回答啦,提供了第二种方式。
第一种方法:(this->*p)(10);
第二种方法:(*this).*p(10);
只有这两种方法访问成员函数指针(也可以访问数据成员指针),(.*)和(->*)是C++新增的运算符。至于编译器会报错是因为你创建的是一个属于CTest类的函数对象,那么必须得使用该类的实例去访问该函数对象,也就是说你调用函数对象时,必须得把该实例的地址和相应的函数实参传进去,当你像上面那样子用的时候,编译器会翻译成这样进行函数调用:
p(10, this),而你直接p(10)调用,明显少了个参数,所以编译器才那样报错。还有问题可以继续问。

50

主题

236

帖子

454

积分

中级会员

Rank: 3Rank: 3

积分
454
 楼主| 发表于 2013-4-18 19:03:10 | 显示全部楼层
zx504287 发表于 2013-4-18 12:53
我已经回答啦,提供了第二种方式。
第一种方法:(this->*p)(10);
第二种方法:(*this).*p(10);

也就是说没有别的方式,只能用this?
你说的理由我还是不能理解,因为this不等于实例对象

罢了,这种问题,我觉得已经没有讨论的意义了。

0

主题

12

帖子

32

积分

注册会员

Rank: 2

积分
32
发表于 2013-4-19 14:01:13 | 显示全部楼层
额……首先,你要求的是在类里调用这个函数对象……我不明白你为什么不直接调用这个函数得了,非得弄个函数指针。所以你必须得说明白你到底想解决的是个什么问题。还有你得先弄明白this到底是个什么东西,不然很多东西都无法理解,你还得明白编译器到底怎么调用你的函数对象的,不然我无法阐述清楚啊。如果要求的是在类外调用的话,那个花样可多了。委托技术便是这个问题的延伸版。

0

主题

12

帖子

32

积分

注册会员

Rank: 2

积分
32
发表于 2013-4-19 15:04:18 | 显示全部楼层
class Test;
typedef void (Test::*pFunc)(int);
struct MemberFunc
{
        Test* pThis;
        pFunc pf;
};
class Test
{
public:
        Test()
        {

        }
        void f(int i)
        {
                cout << "i==" << i <<endl;
        }
        void Set(pFunc pf, Test* pThis)
        {
                func.pf = pf;
                func.pThis = pThis;
        }
        void call()
        {
                ((func.pThis)->*(func.pf))(10);
        }
public:
        MemberFunc func;
};

int main()
{
        Test t;
        t.Set(&Test::f, &t);
        t.call();
}
不知道这个是不是你想要的答案……

0

主题

12

帖子

32

积分

注册会员

Rank: 2

积分
32
发表于 2013-4-19 15:32:55 | 显示全部楼层
class Empty
{

};
typedef void (Empty::*pFunc)(int);
struct MemberFunc
{
        Empty* pThis;
        pFunc pf;
};

class Test
{
public:
        Test()
        {

        }
        void f(int i)
        {
                cout << "i==" << i <<endl;
        }

};

class Function
{
public:
        void set(void (Test::*pf)(int), Test* pThis)
        {
                func.pf = reinterpret_cast<pFunc>(pf);
                func.pThis = reinterpret_cast<Empty*>(pThis);
        }
        void call(int i)
        {
                ((func.pThis)->*(func.pf))(i);
        }
private:
        MemberFunc func;
};

int main()
{
        Test t;

        Function func;
        func.set(&Test::f, &t);
        func.call(10);
}还可以这样子,不知道你是不是想解决类似这样的问题……

11

主题

1238

帖子

1782

积分

金牌会员

Rank: 6Rank: 6

积分
1782
发表于 2013-4-22 13:48:17 | 显示全部楼层
楼主又在写什么新奇东西.......

2

主题

6

帖子

40

积分

注册会员

Rank: 2

积分
40
发表于 2013-4-23 11:11:20 | 显示全部楼层
使用静态类成员函数就可以,因为类在为实例化之前非静态成员函数的地址是未确定的,反之静态类成员函数在类实例化之前就已经分配了地址所以可以在类中来指向静态成员函数。
class cTest2
{
public:
        typedef void (*CommandFunc)(int a);
        static void test(int a)
        {
        }

        void testFunc()
        {
                CommandFunc FuncPrt;
                FuncPrt = test;
        }
protected:
private:
};
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-26 22:52

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表