网易首页 > 网易号 > 正文 申请入驻

C++ 函数指针 及类成员函数指针概述

0
分享至

函数指针是指函数存放在内存的代码区域内,它们同样有地址.如果我们有一个 int test(int a) 的函数,那么,它的地址就是函数的名字,这一点如同数组一样,数组的名字就是数组的起始地址。

函数指针

函数存放在内存的代码区域内,它们同样有地址.如果我们有一个 int test(int a) 的函数,那么,它的地址就是函数的名字,这一点如同数组一样,数组的名字就是数组的起始地址。

函数指针的定义方式

data_types (*func_pointer)( data_types arg1, data_types arg2, ...,data_types argn);

例如:

int test(int a){ return a;}int main(int argc, const char * argv[]){ int (*fp)(int a); fp = test; cout<

注意:函数指针所指向的函数一定要保持函数的返回值类型,函数参数个数,类型一致。

typedef 定义可以简化函数指针的定义

实例

int test(int a){ return a;} int main(int argc, const char * argv[]){ typedef int (*fp)(int a); fp f = test; cout<

函数指针同样是可以作为参数传递给函数的

实例

int test(int a){ return a-1;}int test2(int (*fun)(int),int b){ int c = fun(10)+b; return c;} int main(int argc, const char * argv[]){ typedef int (*fp)(int a); fp f = test; cout<

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

10

利用函数指针,我们可以构成函数指针数组,更明确点的说法是构成指向函数的指针数组。

实例

void t1(){cout<<"test1"<

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

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

基本上要注意的有两点:

  1. 1. 函数指针赋值要使用 &
  2. 2. 使用 .* (实例对象)或者 ->*(实例对象指针)调用类成员函数指针所指向的函数

下面看两个例子:

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

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

实例

//指向类成员函数的函数指针 #include#includeusing 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); 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) 类成员函数指针指向类中的静态成员函数
实例

#includeusing 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)();//打印 A A *b = &a; (b->*p)(); //打印 A /*尽管a.p2本身是个非static变量,但是a.p2是指向static函数的函数指针, **所以下面这就话是错的! */ // p = a.p2;//error void (*pp)(void); pp = &A::funb; pp(); //打印 B return 0; }

总结

类成员函数指针与普通函数指针不是一码事。前者要用 .* 与 ->* 运算符来使用,而后者可以用 * 运算符(称为"解引用"dereference,或称"间址"indirection)。

普通函数指针实际上保存的是函数体的开始地址,因此也称"代码指针",以区别于 C/C++ 最常用的数据指针。

而类成员函数指针就不仅仅是类成员函数的内存起始地址,还需要能解决因为 C++ 的多重继承、虚继承而带来的类实例地址的调整问题,所以类成员函数指针在调用的时候一定要传入类实例对象。

原文来自:https://www.runoob.com/w3cnote/cpp-func-pointer.html
本文地址:https://www.linuxprobe.com/member-function-pointers.html
Linux命令大全:https://www.linuxcool.com/

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
女首富的儿媳不好当!吴静用一招赢得陈丽华认可,比争家产强多了

女首富的儿媳不好当!吴静用一招赢得陈丽华认可,比争家产强多了

喜欢历史的阿繁
2026-04-12 10:40:00
巴拿马总统寻求缓和与中国关系

巴拿马总统寻求缓和与中国关系

参考消息
2026-04-11 19:52:15
郑丽文一行圆满结束大陆参访,离京返台

郑丽文一行圆满结束大陆参访,离京返台

澎湃新闻
2026-04-12 14:40:23
牧夫座空洞直径2.5亿光年,却几乎什么都没有,是谁摧毁了这里?

牧夫座空洞直径2.5亿光年,却几乎什么都没有,是谁摧毁了这里?

观察宇宙
2026-04-11 21:26:55
急了眼了!阿联酋命令巴基斯坦,35亿美元必须马上还清

急了眼了!阿联酋命令巴基斯坦,35亿美元必须马上还清

头条爆料007
2026-04-11 18:33:48
5个月碰瓷30多起!山东一外卖员靠“交规”疯狂“创收”终落网

5个月碰瓷30多起!山东一外卖员靠“交规”疯狂“创收”终落网

娱乐洞察点点
2026-04-12 16:50:28
凤凰卫视记者抛出尖锐难题,郑丽文接下来的回答,让对手没法接招

凤凰卫视记者抛出尖锐难题,郑丽文接下来的回答,让对手没法接招

林子说事
2026-04-11 19:36:01
一个是司令一个是副司令,后来司令被评为上将,副司令却成了大将

一个是司令一个是副司令,后来司令被评为上将,副司令却成了大将

史之铭
2026-04-02 17:18:28
一场惨败的背后:邱彪和山东男篮放过彼此吧,陶汉林一语中的

一场惨败的背后:邱彪和山东男篮放过彼此吧,陶汉林一语中的

姜大叔侃球
2026-04-12 11:14:15
天啊!看到1987年春晚观众席的迟重瑞,才懂陈丽华为啥一见钟情

天啊!看到1987年春晚观众席的迟重瑞,才懂陈丽华为啥一见钟情

真的八卦小学弟
2026-04-12 00:30:12
赌王千金何超蕸去世终年60岁,一生未婚育,何超琼姐弟联名发讣告

赌王千金何超蕸去世终年60岁,一生未婚育,何超琼姐弟联名发讣告

开开森森
2026-04-12 14:54:02
1艘护卫舰,造价36亿,11家船企竞争

1艘护卫舰,造价36亿,11家船企竞争

龙de船人
2026-04-12 15:12:50
曼城看似落后榜首9分实则赢下切尔西就只差3分,下轮迎天王山之战

曼城看似落后榜首9分实则赢下切尔西就只差3分,下轮迎天王山之战

林子说事
2026-04-12 13:00:15
两天两冠!太原赛石洵瑶成赢家,隔空完爆陈熠,新生代她是女二号

两天两冠!太原赛石洵瑶成赢家,隔空完爆陈熠,新生代她是女二号

七七自驾游
2026-04-12 16:40:45
紧急提醒!家里有这款牙膏快停用,砷超标1.5倍,官方已通报下架

紧急提醒!家里有这款牙膏快停用,砷超标1.5倍,官方已通报下架

娱乐的硬糖吖
2026-04-12 03:25:48
美美哒!网友说:谭大扔子没那么大了

美美哒!网友说:谭大扔子没那么大了

挖掘机007
2026-04-12 15:43:46
这张照片是2014年张雪峰和他的妻子李丽婧,在清华大学拍的结婚照

这张照片是2014年张雪峰和他的妻子李丽婧,在清华大学拍的结婚照

喜欢历史的阿繁
2026-04-11 06:47:10
李春平死了

李春平死了

霹雳炮
2025-11-05 22:34:23
中方动作很快,俄专机已抵达,美国人明白,现在容不得特朗普撒野

中方动作很快,俄专机已抵达,美国人明白,现在容不得特朗普撒野

史行途
2026-04-12 15:35:44
今天北京晴天在线最高气温26℃ 明夜至后天雨水或再上线

今天北京晴天在线最高气温26℃ 明夜至后天雨水或再上线

北青网-北京青年报
2026-04-12 15:00:19
2026-04-12 17:36:49
孙有匪 incentive-icons
孙有匪
科技
1595文章数 2008关注度
往期回顾 全部

科技要闻

理想称遭恶意拉踩,东风日产:尊重同行

头条要闻

媒体:长谈未果万斯离开前竖拇指 特朗普挤出僵硬笑容

头条要闻

媒体:长谈未果万斯离开前竖拇指 特朗普挤出僵硬笑容

体育要闻

五大联赛首冠出炉?拜仁或提前4轮卫冕德甲

娱乐要闻

46岁赵达官宣结婚!曾与殷桃谈婚论嫁

财经要闻

三轮磋商谈至深夜 美伊谈判三大议题仍待解

汽车要闻

焕新极氪007/007GT上市 限时19.39万起

态度原创

艺术
时尚
本地
亲子
军事航空

艺术要闻

书法“初学者”如何选帖?这3大重点一定要牢牢记住!

伊姐周六热推:电视剧《八千里路云和月》;综艺《乘风2026》......

本地新闻

12吨巧克力有难,全网化身超级侦探添乱

亲子要闻

一张折线图揭露人类寿命暴增的真正秘密!是儿童死亡率从50%跌到4.3%

军事要闻

美国副总统万斯:美伊谈判未能达成协议

无障碍浏览 进入关怀版