当前位置: 首页 > news >正文

C++指向类成员的函数指针

指向类成员函数的函数指针

定义:类成员函数指针(member function pointer),是 C++ 语言的一类指针数据类型,用于存储一个指定类具有给定的形参列表与返回值类型的成员函数的访问信息。

基本上要注意的有两点:

1、函数指针赋值要使用 &
2、使用 .* (实例对象)或者 ->*(实例对象指针)调用类成员函数指针所指向的函数
下面看两个例子:

A) 类成员函数指针指向类中的非静态成员函数

对于 nonstatic member function (非静态成员函数)取地址,获得该函数在内存中的实际地址

对于 virtual function(虚函数), 其地址在编译时期是未知的,所以对于 virtual member function(虚成员函数)取其地址,所能获得的只是一个索引值

//指向类成员函数的函数指针
#include <iostream>
#include <cstdio>
using namespace std;class A
{public:A(int aa = 0):a(aa){}~A(){}void setA(int aa = 1){a = aa;}virtual void print(){cout << "A: " << a << endl;}virtual void printa(){cout << "A1: " << a << endl;}private:int a;
};class B:public A
{public:B():A(), b(0){}B(int aa, int bb):A(aa), b(bb){}~B(){}virtual void print(){A::print();cout << "B: " << b << endl;}virtual void printa(){A::printa();cout << "B: " << b << endl;}private:int b;
};int main(void)
{A a;B b;void (A::*ptr)(int) = &A::setA;A* pa = &a;//对于非虚函数,返回其在内存的真实地址printf("A::set(): %p\n", &A::setA);//对于虚函数, 返回其在虚函数表的偏移位置printf("B::print(): %p\n", &A::print);printf("B::print(): %p\n", &A::printa);std::thread t = std::thread(&A::setA, a);a.print();a.setA(10);a.print();a.setA(100);a.print();//对于指向类成员函数的函数指针,引用时必须传入一个类对象的this指针,所以必须由类实体调用(pa->*ptr)(1000);a.print();(a.*ptr)(10000);a.print();return 0;
}

执行以上代码,输出结果为:

A::set(): 0x8048a38
B::print(): 0x1
B::print(): 0x5
A: 0
A: 10
A: 100
A: 1000
A: 10000

B) 类成员函数指针指向类中的静态成员函数

#include <iostream>
using namespace std;class A{
public://p1是一个指向非static成员函数的函数指针void (A::*p1)(void);//p2是一个指向static成员函数的函数指针void (*p2)(void);A(){/*对**指向非static成员函数的指针**和**指向static成员函数的指针**的变量的赋值方式是一样的,都是&ClassName::memberVariable形式**区别在于:**对p1只能用非static成员函数赋值**对p2只能用static成员函数赋值****再有,赋值时如果直接&memberVariable,则在VS中报"编译器错误 C2276"**参见:http://msdn.microsoft.com/zh-cn/library/850cstw1.aspx*/p1 =&A::funa; //函数指针赋值一定要使用 &p2 =&A::funb;//p1 =&A::funb;//error//p2 =&A::funa;//error//p1=&funa;//error,编译器错误 C2276//p2=&funb;//error,编译器错误 C2276}void funa(void){puts("A");}static void funb(void){puts("B");}
};int main()
{A a;//p是指向A中非static成员函数的函数指针void (A::*p)(void);(a.*a.p1)(); //打印 A//使用.*(实例对象)或者->*(实例对象指针)调用类成员函数指针所指向的函数p = a.p1;(a.*p)();//打印 AA *b = &a;(b->*p)(); //打印 A/*尽管a.p2本身是个非static变量,但是a.p2是指向static函数的函数指针,**所以下面这就话是错的!*/
//    p = a.p2;//errorvoid (*pp)(void);pp = &A::funb;pp(); //打印 Breturn 0;
}

总结

类成员函数指针与普通函数指针不是一码事。前者要用 .* 与 ->* 运算符来使用,而后者可以用 * 运算符(称为"解引用"dereference,或称"间址"indirection)。普通函数指针实际上保存的是函数体的开始地址,因此也称"代码指针",以区别于 C/C++ 最常用的数据指针。而类成员函数指针就不仅仅是类成员函数的内存起始地址,还需要能解决因为 C++ 的多重继承、虚继承而带来的类实例地址的调整问题,所以类成员函数指针在调用的时候一定要传入类实例对象。

原文连接

https://www.runoob.com/w3cnote/cpp-func-pointer.html

http://www.xdnf.cn/news/815995.html

相关文章:

  • 自己组装电脑一定要注意的事情:风道组建
  • 激光打印机的原理、碳粉分类
  • UNIX命令大全
  • 常见工具识别集锦-Windows应急响应工具
  • 整型变量
  • DL之GCN:GCN算法的架构详解(设计原则/架构流程步骤/GCN模块/BR模块)之详细攻略
  • 数字图像处理标准图像Lena的故事
  • DiscuzX3.4模板W!简论坛风格(适合于资源站)
  • python获取百度搜索框
  • 第1部分: 游戏引擎介绍, 渲染和构造3D世界
  • 锚点(anchorPoint)
  • 百度分享插件的相关参数
  • 360浏览器访问网站直接跳转 se://error/ 问题(无法打开网站)解决方法
  • linux常见的解压命令,linux常见解压命令
  • 【CSS案例】下载进度条
  • C#中ManualResetEvent的Reset,Set,WaitOne
  • 电脑锁屏密码怎么设置?3个步骤快速上锁,打造安全防线
  • AndroidO(8.0) 和 Android P(9.0)
  • Aptana使用入门一:Code Assist
  • element $alert实现字符串换行
  • 6个技巧 全方位解决Windows Defender无法启用问题
  • 盗版WINDOWS今天下载安装了windows genuine Advantage后系统提示让购买正版许可证我该...
  • 0402封装尺寸_PCB常用封装库命名规范及注意事项
  • 键盘HOOK解析
  • 世界著名反垃圾邮件组织的介绍
  • java3D 简介
  • 图解网络:36张图详解网络基础知识
  • HDMI接口基础知识与指南
  • 元心科技加入,龙蜥社区迎来国内领先的智能移动OS厂商
  • chmod命令详细用法