c++二元运算符 ->* 和 .*

->*.*是两个‘二元运算符’ , 用来操作类成员变量和函数
  • &class::member : 对于member为 nonstatic的变量, 取值后返回的是变量在对象内的偏移位置。对于static的成员变量,返回的是成员地址。 nonstatic和static变量取值都可以直接用*
  • &class::func : 返回的是成员函数的地址。对于nonstatic函数,通过返回的指针调用函数需要用二元运算符.*或者->, 对于static函数则直接用 *解引用即可,static函数和普通c函数一样的调用。
  • .*->* 的两个参数分别是 对象指针对象内的非static函数指针
  • 取类成员非static变量取值后返回的是偏移位,是个整型。 那么能不能对一个整型进行static_cast或reinterpret_cast转换,转换成类成员的偏移值呢? --这是不行的。
#include<iostream>

using namespace std;

class classTest {
public:
	classTest(int tmpA) : innerA(tmpA) {};
public:
	void print() { cout << "classTest::print() 123" << endl; }
	void print2() { cout << "classTest::print2() 456" << endl; }
	int innerA;
	int innerA2;
	static int stA;
	static void printSt() { cout << "classTest::printSt" << endl; }
};
int classTest::stA = 33;
// 普通函数
void outPrint() { cout << "outPrint 222" << endl; }

int main()
{
	/* 	不要用cout输出地址或偏移
	cout << &classTest::innerA << endl;   // 1
	cout << &classTest::innerA2 << endl; // 1
	cout << &classTest::print2 << endl; // 1
	cout << &classTest::print << endl; */ // 1
	cout << typeid(&classTest::print).name() << endl; // void (__thiscall classTest::*)(void)
	cout << typeid(&classTest::innerA).name() << endl; // int classTest::*
	
	printf("\n--%x--\n", &classTest::innerA2); // nonstatic 数据成员返回的是偏移值 4
	printf("\n--%x--\n", &classTest::innerA); // 0
	printf("\n--%x--\n", &classTest::print2); // 返回成员函数地址值  c71424
	printf("\n--%x--\n", &classTest::print); // c710dc
	printf("\n--%x--\n", &classTest::stA); // static成员返回的是地址值 c7c008

	classTest ct(3);
	int *pI = &ct.innerA;
	cout << *pI << endl;  // 对成员变量直接用*取值
	void (classTest::*pp)() = &classTest::print;
	//decltype(pp) pp2 = 2; // error  没法隐式转化
	// decltype(&classTest::innerA) pp2 = static_cast<decltype(&classTest::innerA)>(3); //error 偏移值也没法强转
	// decltype(&classTest::innerA) pp2 = reinterpret_cast<decltype(&classTest::innerA)>(3); //error
	(ct.*pp)(); // classTest::print() 123   对成员函数调用需要用 .* 或者 ->*
	// (ct.*(&classTest::printSt))();  error .*不能作用于static函数
	(ct.*(&classTest::print2))();
	
	void (*p)() = outPrint;
	(*p)(); // outPrint 222  对指针*后再调用函数
	p(); // outPrint 222 直接调用函数
	cout << p << endl; // 00C710B4 
	cout << typeid(pp).name() << endl;  // void(__thiscall classTest::*)(void) 成员函数类型
	cout << typeid(p).name() << endl;  // void (__cdecl*)(void) 普通函数类型
	cout << typeid(classTest::printSt).name() << endl; // void __cdecl(void) // static 成员函数
	cout << &classTest::printSt << endl; // 0132143D
	void (*ppS)() = &classTest::printSt;
	ppS(); //  classTest::printSt  static成员和普通外部函数一样访问
	(*ppS)(); //  classTest::printSt
	cout << &classTest::stA << endl;  // 0132C008
	getchar();
}



参考:
C++ 获取类成员函数地址方法 浅析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值