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

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

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

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

    函数成员指针名 = &类名::函数成员名;

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

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

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

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

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

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

    数据成员指针名 = &类名::数据成员名;

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

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

以下是测试代码:

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.youkuaiyun.com/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.youkuaiyun.com/fengbingchun"; // 通过指向成员的指针进行访问
	fprintf(stdout, "addr is: %s\n", ops7.addr_.c_str());

	return 0;
}

执行结果如下图所示:

GitHubhttps://github.com/fengbingchun/Messy_Test

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值