栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

函数指针实例:
复制代码 代码如下:
typedef int (*p)(int,int);//定义一个接受两个int型且返回int型变量的函数指针类型
int func(int x,int y)
{
 printf("func:x=%d,y=%d/n",x,y);
 return (x}
int main()
{
 p fun=func;//定义函数指针并给它赋上一个函数指针
 cout<<"min:"<<(*fun)(4,5)< return 0;
}
   而“指向类成员函数的指针”却多了一个类的区别:
class A
{
public:
 int func(int x,int y)
 {
  printf("A::func:x=%d,y=%d/n",x,y);
  return (x }
};
typedef int (A::*p)(int,int);//指针名前一定要加上所属类型类名 A::的限定
int main()
{
 p fun=&A::func;
 A a;                  //因为成员函数地址的解引用必须要附驻与某个对象的地址,所以我们必须创建某个对象。
 cout<<"min:"<<(a.*fun)(4,5)< return 0;
}

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

接下来 我们可以再扩展一下下:
复制代码 代码如下:
#include
#include
#include
using namespace std;
class A
{
public:
 int func1(int x,int y)
 {
  printf("A::func:x=%d,y=%d/n",x,y);
  return (x }
 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)< cout<<(b.*fun)(4,5)< fun=&A::func2;
 cout<<(a.*fun)(4,5)< cout<<(b.*fun)(4,5)< //fun=&B::func2;         //这样式错误滴,因为不存在派生类的"指向类成员函数的指针"到基类的"指向类成员函数的指针"的隐式转换
 fun=(int (A::*)(int,int))&B::func2;//应该进行强制转换
 cout<<(a.*fun)(4,5)< cout<<(b.*fun)(4,5)<
 p0 fun0=&B::func2;
 cout<<(a.*fun)(4,5)< cout<<(b.*fun)(4,5)<
 fun0=&A::func2;           //正确,因为这里进行了隐式转换
 cout<<(a.*fun)(4,5)< cout<<(b.*fun)(4,5)< //从上面我们不难发现 指向类成员函数的指针基类和派生类的关系和指向类对象的指针基类和派生类的关系完全相反,
 //基类成员函数的布局被认为是派生类成员函数布局的一个子集
 return 0;
}

接下  是有关模板类的类成员函数指针的使用
实例如下:
复制代码 代码如下:
#include
#include
#include
using namespace std;
class A
{
public:
 int func(int x,int y)
 {
  printf("A::func : x=%d,y=%d/n",x,y);
  return (x }
};
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 C
{
public:
 T c;
 void Print()
 {
  int (T::*p)(int,int)=&T::func;
  (c.*p)(4,5);
 }
};
int main()
{
 C ca;
 C cb;
 ca.Print();
 cb.Print();
 return 0;
}

从上面 可以很清晰地看到。。其实它和普通的模板没有什么区别。。只不过将限定名称该为参数名酒OK啦。。。
嘿嘿。。。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/66303.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号