类中成员函数及普通函数地址获取方式

代码准备

头文件:Calc.h

#pragma once

class Calc
{
public:
	int add(int,int);//函数声明
	static int sub(int,int);//函数声明
public:
	int b;//定义了一个成员变量
	static int a;//声明了一个静态成员变量,注意这里不是定义,静态成员变量的定义必须在类的定义的外部
};
//int Calc::a = 10;//不要把静态成员变量的定义写到头文件里,否则在其他多个源文件引入此头文件时,会报定义重复
//非类中的普通函数的声明
void normal_fun(int k);

源文件 Calc.cpp

#include "Calc.h"
int Calc::a = 0;//在源文件中定义静态成员变量并初始化
int Calc::add(int i, int j)//定义函数
{   
    return i + j;
}
int Calc::sub(int i, int j)//定义函数
{
    return i - j;
}

测试演示

测试代码: test.cpp

#include <iostream>
using namespace std;
#include "Calc.h"

//非类中的普通函数的定义
void normal_fun(int k) {
	cout << __func__ << endl;
}

//定义一个命名空间MyNs 
namespace MyNs {
	//声明一个普通函数
	void normal_fun_2(int k);
}
//命名空间内的函数的定义
void MyNs::normal_fun_2(int k)
{
	cout << __func__ << endl;
}

int main(int argc, char* argv[])
{
    //打印Calc类成员函数的地址
	printf("add函数的地址:%p\n", &Calc::add);
	//打印Calc类静态成员函数的地址
	printf("sub函数的地址:%p\n", &Calc::sub);
	//打印Calc类静态成员变量的地址
	printf("变量a的地址:%p\n", &Calc::a);

	//打印非类中的全局普通函数的地址
	printf("normal_fun_1函数地址:%p\n", normal_fun_1);
	//打印命名空间中的普通函数的地址
	printf("normal_fun_2函数地址:%p\n", MyNs::normal_fun_2);
}

注意事项

注意获取一个类中成员函数指针的语法要求很严格:
1.必须有限定符:例如&add或者&sub不对。即使在类Calc的作用域内也不行。
2.必须使用取地址符号:例如直接写ClassName::add不行。(虽然普通函数指针可以这样) 所以,必须要这样写:&ClassName::add。
3.不能使用括号:例如&(ClassName::add)不对,但是经测试发现这样也是可以的。
4.普通函数可以直接用函数名当作函数地址 或者 命名空间里的函数通过NameSpace::normal_fun_2的方式,前面不需要加&。

成员函数类型申明

可以像普通函数一样采用typedef或者using 运算符将函数指针类型重命名,这样更好看一些。普通函数指针的申明

void test() {
	int (Calc::*addFun)(int,int) = &Calc::add;//addFun就是成员函数add的函数指针
	Calc c;        //.*的用法,经由对象调用 即对象动态调用符号.*
	int ret = (c.*addFun)(7, 6); 
	cout << __func__ << "	ret=" << ret<< endl; //13
	Calc* pc = &c;  //->*的用法,经由对象指针调用 即对象指针动态调用符号->*
	ret = (pc->*addFun)(6,3);  
	cout << __func__ << "	ret=" << ret << endl; //9
}

注意:虽然我们获取到了成员函数的地址,或者指向成员函数的指针,但是成员函数不像全局函数那样直接可以使用。而成员函数必须由对象或对象指针来调用。

void test1() {
	int (Calc:: *addFun)(int, int);//定义了一个Calc类下含有两个int型参数,返回类型为int的 成员函数指针addFun
	typedef int (Calc:: *Pmt)(int, int);//成员函数指针类型的别名为Pmt
	//using Pmt = int (Calc::*)(int, int);//等价于上面的typedef定义。

	addFun = &Calc::add;
	Pmt pmt = &Calc::add;
	Calc  c;
	int ret1 = (c.*addFun)(6,5);
	cout << __func__ << "	ret1=" << ret1 << endl;//11

	int ret2 = (c.*pmt)(6, 6);
	cout << __func__ << "	ret2=" << ret2 << endl;//12
}

测试演示

int main(int argc, char* argv[])
{
	test();
	test1();
}

总的打印输出

在这里插入图片描述

成员函数重载

成员函数存在重载时,如何获取指定成员函数的指针呢 。请看内有成员重载函数指针获取方式

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值