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;
}
执行结果如下图所示: