C++指向类成员函数的指针详细解析
时间:2022-03-05 04:50:28
首先 函数指针是指向一组同类型的函数的指针;而类成员函数我们也可以相似的认为,它是指向同类中同一组类型的成员函数的指针,当然这里的成员函数更准确的讲应该是指非静态的成员函数。前者是直接指向函数地址的,而后者我们从字面上也可以知道 它肯定是跟类和对象有着关系的。
函数指针实例:
typedef int (*p)(int,int);//定义一个接受两个int型且返回int型变量的函数指针类型
int func(int x,int y)
{
printf("func:x=%d,y=%d/n",x,y);
return (x<y?x:y);
}
int main()
{
p fun=func;//定义函数指针并给它赋上一个函数指针
cout<<"min:"<<(*fun)(4,5)<<endl;//为什么*fun需要用()扩起来呢?因为*的运算符优先级比()低,如果不用()就成了*(fun())
return 0;
}
而“指向类成员函数的指针”却多了一个类的区别:
class A
{
public:
int func(int x,int y)
{
printf("A::func:x=%d,y=%d/n",x,y);
return (x<y?x:y);
}
};
typedef int (A::*p)(int,int);//指针名前一定要加上所属类型类名 A::的限定
int main()
{
p fun=&A::func;
A a; //因为成员函数地址的解引用必须要附驻与某个对象的地址,所以我们必须创建某个对象。
cout<<"min:"<<(a.*fun)(4,5)<<endl;
return 0;
}
嘿嘿。。只是用起来 .* 感觉怪怪滴。
接下来 我们可以再扩展一下下:
#include <tchar.h>
#include <iostream>
#include <stdio.h>
using namespace std;
class A
{
public:
int func1(int x,int y)
{
printf("A::func:x=%d,y=%d/n",x,y);
return (x<y?x:y);
}
virtual int func2(int x,int y)
{
printf("A::func:x=%d,y=%d/n",x,y);
return (x>y?x:y);
}
};
class B:public A
{
public:
virtual int func2(int x,int y)
{
printf("B::func:x=%d,y=%d/n",x,y);
return (x+y);
}
};
typedef int (A::*p)(int,int);//指针名前一定要加上所属类型类名 A::的限定
typedef int (B::*p0)(int,int);
int main()
{
A a; //因为成员函数地址的解引用必须要附驻与某个对象的地址,所以我们必须创建某个对象。
p fun=&A::func1;
cout<<(a.*fun)(4,5)<<endl;
cout<<(b.*fun)(4,5)<<endl<<endl;
fun=&A::func2;
cout<<(a.*fun)(4,5)<<endl;//请注意这里调用的是虚函数,嘿嘿 还真神奇 类成员函数指针也支持多态。
cout<<(b.*fun)(4,5)<<endl<<endl;
//fun=&B::func2; //这样式错误滴,因为不存在派生类的"指向类成员函数的指针"到基类的"指向类成员函数的指针"的隐式转换
fun=(int (A::*)(int,int))&B::func2;//应该进行强制转换
cout<<(a.*fun)(4,5)<<endl;
cout<<(b.*fun)(4,5)<<endl<<endl;
p0 fun0=&B::func2;
cout<<(a.*fun)(4,5)<<endl;
cout<<(b.*fun)(4,5)<<endl<<endl;
fun0=&A::func2; //正确,因为这里进行了隐式转换
cout<<(a.*fun)(4,5)<<endl;
cout<<(b.*fun)(4,5)<<endl<<endl;
//从上面我们不难发现 指向类成员函数的指针基类和派生类的关系和指向类对象的指针基类和派生类的关系完全相反,
//基类成员函数的布局被认为是派生类成员函数布局的一个子集
return 0;
}
接下 是有关模板类的类成员函数指针的使用
实例如下:
#include <tchar.h>
#include <iostream>
#include <stdio.h>
using namespace std;
class A
{
public:
int func(int x,int y)
{
printf("A::func : x=%d,y=%d/n",x,y);
return (x<y?x:y);
}
};
class B
{
public:
int func(int x,int y)
{
printf("B::func : x=%d,y=%d/n",x,y);
return (x>y?x:y);
}
};
template<class T>
class C
{
public:
T c;
void Print()
{
int (T::*p)(int,int)=&T::func;
(c.*p)(4,5);
}
};
int main()
{
C<A> ca;
C<B> cb;
ca.Print();
cb.Print();
return 0;
}
从上面 可以很清晰地看到。。其实它和普通的模板没有什么区别。。只不过将限定名称该为参数名酒OK啦。。。
嘿嘿。。。
标签:类成员函数,指针,c++
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java泛型的类型擦除示例详解
2023-07-02 13:38:17
![](https://img.aspxhome.com/file/2023/0/78330_0s.png)
JavaEE中用response向客户端输出中文数据乱码问题分析
2022-07-14 00:39:27
![](https://img.aspxhome.com/file/2023/8/122978_0s.png)
obix协议在java中的配置和使用详解
2023-11-25 20:59:42
![](https://img.aspxhome.com/file/2023/5/60275_0s.jpg)
android开发仿ios的UIScrollView实例代码
2023-08-07 01:55:20
详解Java 集合系列(三)—— LinkedList
2022-01-30 16:49:10
![](https://img.aspxhome.com/file/2023/4/64054_0s.jpg)
Java字符串的intern方法有何奥妙之处
2022-07-21 13:38:16
![](https://img.aspxhome.com/file/2023/8/118828_0s.png)
C#.net中的类型转换详细介绍
2021-09-20 04:14:01
C# InitializeComponent()方法案例详解
2022-06-12 03:07:06
解决JTable排序问题的方法详解
2023-02-07 08:53:42
Java实现两人五子棋游戏(三) 画出棋子
2021-05-29 04:53:53
![](https://img.aspxhome.com/file/2023/0/104060_0s.png)
C#找不到类型名"SqlConnection"的有效解决方法
2022-05-10 09:47:26
![](https://img.aspxhome.com/file/2023/4/100204_0s.png)
详解java8在Collection中新增加的方法removeIf
2022-06-04 20:51:45
C++ 二维(多维)vector添加一个空项问题
2022-10-10 14:44:23
Android使用ViewPager实现启动引导页
2023-02-03 12:28:28
![](https://img.aspxhome.com/file/2023/8/91018_0s.png)
java多次嵌套循环查询数据库导致代码中数据处理慢的解决
2023-10-28 22:17:50
Java基本类型与byte数组之间相互转换方法
2023-11-16 22:49:23
Android仿微信清理内存图表动画(解决surfaceView屏幕闪烁问题)demo实例详解
2023-05-31 15:35:27
![](https://img.aspxhome.com/file/2023/7/111737_0s.gif)
ZooKeeper入门教程一简介与核心概念
2022-11-24 18:36:00
![](https://img.aspxhome.com/file/2023/9/65749_0s.jpg)
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
2023-11-26 15:05:59
Android简单实现圆盘抽奖界面
2022-07-25 08:35:27
![](https://img.aspxhome.com/file/2023/2/101872_0s.jpg)