指向类成员的指针运算符 .* 和 ->* 返回表达式左侧指定的对象的特定类成员的值。右侧必须指定类的成员。以下示例显示如何使用这些运算符:
// compile with: /EHsc
#include <iostream>
using namespace std;
class Testpm {
public:
void m_func1() { cout << "m_func1\n"; }
int m_num;
};
// 定义两个类型 pmfn 和pmd.
// 这两个类型分另是指向类成员的 m_func1() 和 m_num指针。
void (Testpm::* pmfn)() = &Testpm::m_func1;
int Testpm::* pmd = &Testpm::m_num;
int main()
{
Testpm ATestpm;
Testpm* pTestpm = new Testpm;
// 访问成员函数
(ATestpm.*pmfn)(); //相当于解引用,指针存的是函数地址
(pTestpm->*pmfn)(); // 要求使用(),类为 * 绑定不如函数紧密
// 访问数据成员
ATestpm.*pmd = 1;
pTestpm->*pmd = 2;
cout << ATestpm.*pmd << endl
<< pTestpm->*pmd << endl;
delete pTestpm;
}
//输出:
m_func1
m_func1
1
2
在前面的示例中,指向成员的指针 pmfn 用于调用成员函数 m_func1。另一个指向成员的指针 pmd 用于访问 m_num 成员。
二元运算符 .* 将其第一个操作数(必须是类类型的对象)与第二个操作数(必须是指向成员的指针类型)组合在一起。
二元运算符 ->* 将其第一个操作数(必须是类类型的对象的指针)与第二个操作数(必须是指向成员的指针类型)组合在一起。
在包含 .* 运算符的表达式中,第一个操作数必须是第二个操作数中指定的指向成员的指针的类类型,并且可由该指针访问,或者属于明确从该类派生并可由该类访问的可访问类型。
在包含 ->* 运算符的表达式中,第一个操作数必须是第二个操作数中指定的类型的“指向类类型的指针”类型,或者必须是明确从该类派生的类型。
例如,考虑下面的类和片段:
class BaseClass {
public:
BaseClass(); // 基类构造函数.
void Func1();
};
// 声明一个指向成员函数 Func1的指针 。
void (BaseClass::* pmfnFunc1)() = &BaseClass::Func1;
class Derived : public BaseClass {
public:
Derived(); // 派生类构造函数.
void Func2();
};
// 声明一个指向成员函数 Func2的指针 。
void (Derived::* pmfnFunc2)() = &Derived::Func2;
int _tmain(int argc, _TCHAR* argv[])
{
BaseClass ABase;
Derived ADerived;
(ABase.*pmfnFunc1)(); // OK: 定义了一个基类.
(ABase.*pmfnFunc2)(); // 错: 不能使用基类去访问指向派生类成员的指针
(ADerived.*pmfnFunc1)(); // OK:
// derived from BaseClass.
(ADerived.*pmfnFunc2)(); // OK:
system("pause");
return 0;
}