1 区别
- 函数指针是通过指向函数的指针间接调用函数。函数指针可以实现对参数类型、参数顺序、返回值都相同的函数进行封装,是多态的一种实现方式。
- 类的非静态成员函数,第一个参数实际为隐形的this指针,因此,类的成员函数的指针和一般函数的指针的表现形式不一样。
2 普通函数指针
- 函数指针的声明中需要包括了函数的参数类型、顺序和返回值,只能把相匹配的函数地址赋值给函数指针。
- 为了封装相同类型的函数,可以把函数指针作为通用接口函数的参数,并通过函数指针来间接调用所封装的函数。
#include <iostream>
//指向函数的指针
typedef int (*pFun)(int, int);
int maxFun(int a, int b)
{
return a < b ? b : a;
}
int minFun(int a, int b)
{
return a < b ? a : b;
}
//通用函数接口,实现对maxFun, minFun函数类型的封装
int commonFun(pFun fun, int a, int b)
{
return (*fun)(a, b);
}
int main()
{
int a = 1;
int b = 2;
std::cout << commonFun(&maxFun, a, b) << std::endl;
std::cout << commonFun(&minFun, a, b) << std::endl;
}
3 类成员函数指针
- 类的静态成员函数采用与一般函数指针相同的调用方式。
- 因this指针的影响,类的非静态成员函数与一般函数指针是不兼容的。而且,不同类的this指针是不一样的,因此,指向不同类的非静态成员函数的指针也是不兼容的。
- 指向类的非静态成员函数的指针,在声明时就需要添加类名。
#include <iostream>
class CA;
//指向类的非静态成员函数的指针
typedef int (CA::*pClassFun)(int, int);
//指向一般函数的指针
typedef int (*pGeneralFun)(int, int);
class CA
{
public:
int maxFun(int a, int b)
{
return a < b ? b : a;
}
int minFun(int a, int b)
{
return a < b ? a : b;
}
static int sumFun(int a, int b)
{
return a + b;
}
//类内部的接口函数,实现对类的非静态成员函数的封装
int commonFun(pClassFun fun, int a, int b)
{
//不要写成:
// return (*fun)(a, b) ;
return (this->*fun)(a, b);
}
};
//类外部的接口函数,实现对类的非静态成员函数的封装
int commonFun(CA* pCA, pClassFun fun, int a, int b)
{
return (pCA->*fun)(a, b);
}
//类外部的接口函数,实现对类的静态成员函数的封装
int commonGeneralFun(pGeneralFun fun, int a, int b)
{
return (*fun)(a, b);
}
int main()
{
CA ca;
int a = 1;
int b = 2;
//不要写成如下: -----------(A)
// ca.commonFun(CA::maxFun), a, b)
// ca.commonFun(&(CA::maxFun), a, b)
std::cout << ca.commonFun(&CA::maxFun, a, b) << std::endl;
std::cout << ca.commonFun(&CA::minFun, a, b) << std::endl;
std::cout << commonFun(&ca, &CA::maxFun, a, b) << std::endl;
std::cout << commonFun(&ca, &CA::minFun, a, b) << std::endl;
std::cout << commonGeneralFun(&(CA::sumFun), a, b) << std::endl;
return 0;
}
飞信天下注:
上面实例与原文有所不同。
比如错误写法A。
原因如下:
在C++语言中,对于一个由类名 + :: + 成员名(学名叫“quilified-id”),比如:A::x,只有当x是A类的静态成员的时候,A::x才能表示一个左值。
而对于函数类型到函数指针类型的默认转换,只有当函数类型是左值的时候才行。所有对于非静态的成员函数,就不存在这种从函数类型到函数指针类型的默认转换,于是编译器也就不知道这个p = A::f
参考链接:http://topic.csdn.net/t/20060906/11/5002223.html
4 不同类的成员函数进行统一调用
#include <iostream>
class CA
{
public:
int maxFun(int a, int b)
{
return a < b ? b : a;
}
};
class CB
{
public:
float minFun(float a, float b)
{
return a < b ? a : b;
}
};
template <typename ClassType, typename ParaType>
class CC
{
public:
//函数指针类型模板
typedef ParaType (ClassType::*pFun)(ParaType, ParaType);
//函数指针函数模块
ParaType commonFun(ClassType* pClass, pFun fun, ParaType a, ParaType b)
{
return (pClass->*fun)(a, b);
}
};
int main()
{
int a = 1;
int b = 2;
CA ca;
CB cb;
CC<CA, int> cc_ca;
CC<CB, float> cc_cb;
std::cout << cc_ca.commonFun(&ca, &CA::maxFun, a, b) << std::endl;
std::cout << cc_cb.commonFun(&cb, &CB::minFun, a, b) << std::endl;
return 0;
}
参考文献:
[1]https://www.cnblogs.com/xianyunhe/archive/2011/11/26/2264709.html 作者:闲云鹤
飞信天下注
转发本文时,有所改动。