C++类的成员函数指针

条款一 类的成员函数指针变量之间可相互强转:

class A
{};

class B
{};

class C
{};

typedef void (A::*AFun)(void);
typedef int (B::*BFun)(int, int);
typedef void (C::*CFun)(double);

AFun pafun;
BFun pbfun;
CFun pcfun;

//A,B,C类之间没有任何关系,虽然以下转换都是OK的,但基本上是没有任何意义的
pafun = (AFun)pbfun;    //OK
pafun = (AFun)pcfun;    //OK
pbfun = (BFun)pafun;    //OK
pbfun = (BFun)pcfun;    //OK
pcfun = (CFun)pafun;    //OK
pcfun = (CFun)pbfun;    //OK


条款二 类的成员函数指针的使用:

//A类与B类的定义
class A
{
public:
    void Test()
    {
        cout << "A::Test()" << endl;
    }
};

class B : public A
{
public:
    void Test()
    {
        cout << "B::Test()" << endl;
    }
};

//定义类的成员函数指针
typedef void (A::*A_mFun)(void);
typedef void (B::*B_mFun)(void);

//Code
A a;
B b;
A_mFun pAFun = &(A::Test);  //Note:Test成员函数必须为public,否则会报错
B_mFun pBFun = &(B::Test);  //Note:Test成员函数必须为public,否则会报错
(a.*pAFun)();               //输出A::Test()
(b.*pBFun)();               //输出B::Test()
(b.*pAFun)();               //输出A::Test()

A* pA = &a;
B* pB = &b;
(pA->*pAFun)();             //输出A::Test()
(pB->*pBFun)();             //输出B::Test()
(pB->*pAFun)();             //输出A::Test(),B*变量可赋值给A*变量

//******Error******
(pA->*pBFun)();            //Error: cannot convert from 'A *' to 'B *'
                           //Error:  cannot dereference a 'B_mFun' on a 'A *'
//*****************

//******OK******
B* pB_new = (B*)pA;        //强转但本质上是有缺失的     
(pB_new->*pBFun)();        //输出B::Test(),虽OK但切记勿这样使用,此处仅当实验演示
//本质上类的成员函数就是带this指针的函数,但在使用时编译器上会增加一些限制,
//比如类的成员函数指针不能和一般的变量指针及一般的函数指针变量之间互相强转等,这在前面随笔中有提到
//**************
//以下才是真正有意义的,在MFC的框架机制中运用较多
//用基类变量指针+基类成员函数指针调用子类的函数
A_mFun pAFun_B = (A_mFun)&(B::Test);
A* pA_B = &b;
(pA_B->*pAFun_B)();          //输出B::Test()

//例如:
//对话框的消息映射有:
ON_BN_CLICKED(IDC_BTN_NEW_DLG, &CTestDlg::OnBnClickedBtnNewDlg)
//将ID为IDC_BTN_NEW_DLG的按钮的响应事件映射为CTestDlg的成员函数OnBnClickedBtnNewDlg
//我们现在来详细研究下ON_BN_CLICKED
#define ON_BN_CLICKED(id, memberFxn) \
    ON_CONTROL(BN_CLICKED, id, memberFxn)
#define ON_CONTROL(wNotifyCode, id, memberFxn) \
{ WM_COMMAND, (WORD)wNotifyCode, (WORD)id, (WORD)id, AfxSigCmd_v, \
    (static_cast< AFX_PMSG > (memberFxn)) },
typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);
//可以看到这里将子类成员函数的地址赋给了基类成员函数指针类型的变量

转载至:http://www.cnblogs.com/Hisin/archive/2012/04/30/2477119.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值