C++指向类成员函数的指针详细解析

 更新时间:2013年08月20日 09:14:40   作者:  
由于这几天在开发中要用到函数指针,所以就整理了一下关于函数指针的概念

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

函数指针实例:

复制代码 代码如下:

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啦。。。
嘿嘿。。。

相关文章

  • mac 配置Clion运行C和C++的环境的详细步骤

    mac 配置Clion运行C和C++的环境的详细步骤

    这篇文章主要介绍了mac 配置Clion运行C和C++的环境的步骤详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • C++二叉树的前序中序后序非递归实现方法详细讲解

    C++二叉树的前序中序后序非递归实现方法详细讲解

    前序遍历的顺序是根、左、右。任何一颗树都可以认为分为左路节点,左路节点的右子树。先访问左路节点,再来访问左路节点的右子树。把访问左路节点的右子树看成一个子问题,就可以完整递归访问了
    2023-03-03
  • C++各种数据类型所占内存大小详解

    C++各种数据类型所占内存大小详解

    这篇文章主要介绍了C++各种数据类型所占内存大小,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • C语言水仙花数的实现

    C语言水仙花数的实现

    这篇文章主要介绍了C语言水仙花数的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • QML与C++几种交互方式

    QML与C++几种交互方式

    QML作为构建界面的语言是非常简洁的,但是界面的后台有些时候是经常要与C++交互的,本文主要介绍了QML与C++几种交互方式,感兴趣的可以了解一下
    2024-04-04
  • C++之Qt5双缓冲机制案例教程

    C++之Qt5双缓冲机制案例教程

    这篇文章主要介绍了C++之Qt5双缓冲机制案例教程,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++使用string的大数除法运算(4)

    C++使用string的大数除法运算(4)

    这篇文章主要为大家详细介绍了C++使用string的大数除法运算,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • C++ 中CloseHandle 函数--关闭一个句柄

    C++ 中CloseHandle 函数--关闭一个句柄

    这篇文章主要介绍了C++ 中CloseHandle 函数--关闭一个句柄的相关资料,需要的朋友可以参考下
    2017-05-05
  • C++面试八股文之如何避免死锁详解

    C++面试八股文之如何避免死锁详解

    在C++中,锁(Lock)是一种同步工具,用于保护共享资源,防止多个线程同时访问,那么如何避免死锁的情况出现呢,下面就为大家简单讲讲
    2023-07-07
  • 基于QT5实现一个时钟桌面

    基于QT5实现一个时钟桌面

    这篇文章主要介绍了利用QT5实现的一个时钟桌面,文中的示例代码讲解详细,对我们学习或工作有一定的帮助,感兴趣的小伙伴可以了解一下
    2022-01-01

最新评论