C++法则22:运算符 ::* 和 ->* 和 ::* 是独特的整体运算符,是不可分的。
1. ::*
(成员指针声明符)
作用:用于声明一个指向类成员的指针。
语法:
ReturnType (ClassName::*pointerName) = &ClassName::MemberName;
示例:
class MyClass { public:int value;void print() { std::cout << value; } };// 指向成员的指针 int MyClass::*ptr_to_value = &MyClass::value; void (MyClass::*ptr_to_func)() = &MyClass::print;
2. ->*
(通过对象指针访问成员指针)
作用:通过对象指针(
ClassName*
)和成员指针(ClassName::*
)访问成员。语法:
(objectPtr->*memberPointer)
示例:
MyClass obj; MyClass* objPtr = &obj;// 通过 ->* 访问成员 (objPtr->*ptr_to_value) = 42; // 等价于 obj.value = 42 (objPtr->*ptr_to_func)(); // 调用 obj.print()
3. .*
(通过对象访问成员指针)
作用:通过对象(
ClassName
)和成员指针(ClassName::*
)访问成员。语法:
(object.*memberPointer)
示例:
MyClass obj;// 通过 .* 访问成员 (obj.*ptr_to_value) = 42; // 等价于 obj.value = 42 (obj.*ptr_to_func)(); // 调用 obj.print()
关键点:
不可分割性:
::*
、->*
和.*
是独立的运算符,不能拆开(例如->*
不是->
和*
的组合)。它们的优先级和结合性是语言规定的,与其他运算符不同。
成员指针的特殊性:
成员指针不是普通指针,而是与类关联的“偏移”或“访问方式”。
需要结合对象或对象指针才能实际访问成员。
使用场景:
常用于回调、泛型编程或需要动态选择成员的情况。
完整示例:
#include <iostream>class MyClass {
public:int value = 0;void print() { std::cout << "Value: " << value << std::endl; }
};int main() {// 声明成员指针int MyClass::*ptr_to_value = &MyClass::value;void (MyClass::*ptr_to_func)() = &MyClass::print;MyClass obj;MyClass* objPtr = &obj;// 通过 .* 访问(obj.*ptr_to_value) = 10;(obj.*ptr_to_func)();// 通过 ->* 访问(objPtr->*ptr_to_value) = 20;(objPtr->*ptr_to_func)();return 0;
}
输出:
text
Value: 10 Value: 20