How to obtain the addresses of member functions and ordinary functions in a class

Code preparation

head File: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);

Source FileCalc.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 demo

Test code: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);
}

Precautions

Note that the syntax requirements for obtaining a member function pointer in a class are very strict:
1. There must be a qualifier: such as &add or &sub is incorrect. Not even within Calc-like scope.
2. The address symbol must be used: for example, writing ClassName::add directly will not work. (Although ordinary function pointers can do this) Therefore, it must be written like this: &ClassName::add.
3. Brackets cannot be used: for example, &(ClassName::add) is incorrect, but after testing, it was found that this is also possible.
4. Ordinary functions can directly use the function name as the function address or the function in the namespace through NameSpace::normal_fun_2, without adding & in front.

Member function type declaration

You can use the typedef or using operator to rename the function pointer type like a normal function, which makes it look better. Declaration of ordinary function pointers

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
}

注意: Although we get the address of the member function or the pointer to the member function, the member function is not directly available like the global function. Member functions must be called by objects or object pointers.

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
}

test demo

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

total printout

Insert image description here

Guess you like

Origin blog.csdn.net/adminstate/article/details/135080630