指向类成员函数的指针(转)

原文:https://blog.csdn.net/jinjinClouded/article/details/5189540?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2

 参考:

https://blog.csdn.net/weixin_34107955/article/details/94019091

https://www.cnblogs.com/zhoug2020/p/11394408.html

https://www.arduino.cn/thread-42263-1-1.html

      最近在开发中用到了函数指针,于是想整理了一下有关函数指针的概念。O(∩_∩)O~

     首先 函数指针是指向一组同类型的函数的指针;而类成员函数我们也可以相似的认为,它是指向同类中同一组类型的成员函数的指针,当然这里的成员函数更准确的讲应该是指非静态的成员函数。前者是直接指向函数地址的,而后者我们从字面上也可以知道 它肯定是跟类和对象有着关系的。

     函数指针实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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;
}

 

嘿嘿。。只是用起来 .*  感觉怪怪滴。

 

接下来 我们可以再扩展一下下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#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;                   //因为成员函数地址的解引用必须要附驻与某个对象的地址,所以我们必须创建某个对象。
 B b;
 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;<br> //从上面我们不难发现 指向类成员函数的指针基类和派生类的关系和指向类对象的指针基类和派生类的关系完全相反,<br> //基类成员函数的布局被认为是派生类成员函数布局的一个子集<br> return 0;<br>}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
A::func:x=4,y=5/n4
A::func:x=4,y=5/n4
 
A::func:x=4,y=5/n5
B::func:x=4,y=5/n9
 
A::func:x=4,y=5/n5
B::func:x=4,y=5/n9
 
A::func:x=4,y=5/n5
B::func:x=4,y=5/n9
 
A::func:x=4,y=5/n5
B::func:x=4,y=5/n9

  

接下  是有关模板类的类成员函数指针的使用

实例如下:

复制代码
#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啦。。。

嘿嘿。。。

 

 

posted on   lh03061238  阅读(225)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示