C++中指向类成员指针的用法

C++中,指向类的成员指针包含两种:

(1).指向类的成员函数的指针:

类型 (类名::* 函数成员指针名)(参数表);

函数成员指针名 = &类名::函数成员名;
class CTest
{
public:
	int testAdd(int a, int b) { return a + b; }
public:
	std::string				m_str;
};

int (CTest::* pFunAdd)(int, int);
pFunAdd = &CTest::testAdd;

也可将以上两条语句调整为一条语句:

类型 (类名::* 函数成员指针名)(参数表) = &类名::函数成员名;
int (CTest::* pFunAdd2)(int, int) = &CTest::testAdd;

类成员函数指针,是C++语言的一类指针数据类型,用于存储一个指定类具有给定的形参列表与返回值类型的成员函数的访问信息。

使用::*声明一个成员指针类型,或者定义一个成员指针变量。使用.*或者->*调用类成员函数指针所指向的函数,这时必须绑定于成员指针所属类的一个实例的地址。

	int ret = (test.*pFunAdd)(1, 2);
	ret = (pTest->*pFunAdd)(2, 3);
	ret = (pTest->*pFunAdd2)(3, 4);

(2).指向类的数据成员的指针:

类的数据成员的指针不能指向私有数据成员

类型 类名::* 数据成员指针名;

数据成员指针名 = &类名::数据成员名;
	std::string CTest::* str;
	str = &CTest::m_str;

也可将以上两条语句调整为一条语句:

类型 类名::* 数据成员指针名 = &类名::数据成员名;
std::string CTest::* str1 = &CTest::m_str;

使用:

	std::string CTest::* str;
	str = &CTest::m_str;
	test.*str = "456";
	std::cout << test.m_str << std::endl;

	std::string CTest::* str1 = &CTest::m_str;
	pTest->*str1 = "789";
	std::cout << pTest->m_str << std::endl;

以下是测试代码:

class Ops {
public:
	Ops() = default;
	Ops(const int* p1, const int* p2) : value1_(p1), value2_(p2) {}
	Ops(const std::string& str) : addr_(str) {}
 
	int add(int a, int b) { return (a + b); }
	void sub(int a, int b) { fprintf(stdout, "sub: %d\n", (a - b)); }
 
	int (Ops::* op)(int, int);
	
	const int *value1_ = nullptr, *value2_ = nullptr;
	std::string addr_ = "";
};
 
const int* Ops::* select()
{
	std::random_device rd; std::mt19937 generator(rd()); // 每次产生不固定的不同的值
	std::uniform_int_distribution<int> distribution(0, 2);
 
	if (distribution(generator)) return &Ops::value1_;
	else return &Ops::value2_;
}
 
void print(int a, int b, Ops& ops, int (Ops::* fp)(int, int))
{
	int value = (ops.*fp)(a, b);
	fprintf(stdout, "value: %d\n", value);
}
 
int test_class3()
{
	// 类的成员函数
	int (Ops::* func1)(int, int); // 一个类成员函数指针变量func1的定义
	func1 = &Ops::add; // 类成员函数指针变量func1被赋值
 
	Ops ops, *p;
	p = &ops;
	int ret = (ops.*func1)(2, 3); // 对实例ops,调用成员函数指针变量func1所指的函数
	fprintf(stdout, "add: %d\n", ret);
	ret = (p->*func1)(-2, -3);  // 对p所指的实例,调用成员函数指针变量func1所指的函数
	fprintf(stdout, "add2: %d\n", ret);
 
	void (Ops::* func2)(int, int);
	func2 = &Ops::sub; // 函数指针赋值要使用&
	(ops.*func2)(9, 3); 
	(ops.*func2)(3, 9);
 
	Ops ops2;
	int (Ops::* func3)(int, int) = &Ops::add; // 定义类成员函数指针并赋值
	ret = (ops2.*func3)(7, 4);
	fprintf(stdout, "add3: %d\n", ret);
 
	Ops ops5;
	print(1, 6, ops5, &Ops::add);
 
	Ops ops6;
	ops6.op = &Ops::add;
	fprintf(stdout, "value2: %d\n", (ops6.*(ops6.op))(-2, -6));
 
	// 类的数据成员
	const int a = 13, b = 15;
	Ops ops3(&a, &b);
 
	const int* Ops::* value = select();
	fprintf(stdout, "value1: %d\n", *(ops3.*value));
 
	std::string Ops::* str = &Ops::addr_; // 定义时和类关联
	Ops ops4("https://blog.csdn.net/fengbingchun");
	fprintf(stdout, "addr: %s\n", (ops4.*str).c_str()); // 使用时和对象关联
 
	Ops ops7;
	ops7.addr_ = "https://github.com/fengbingchun"; // 直接访问
	fprintf(stdout, "addr is: %s\n", ops7.addr_.c_str());
	std::string Ops::* addr2 = &Ops::addr_;
	ops7.*addr2 = "https://blog.csdn.net/fengbingchun"; // 通过指向成员的指针进行访问
	fprintf(stdout, "addr is: %s\n", ops7.addr_.c_str());
 
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值