背景
最近在进行C++开发时,发现自己对于普通的变量指针、函数指针与类的成员指针的理解出现了偏差和混乱,所以在这边文章中引用了<C++ Primer>书籍中的片段结合示例进行C++类成员指针的讲解,包含以下两点,
- 类数据成员指针
- 类成员函数指针
成员指针
成员指针(point to member)是指可以指向类的非静态成员的指针。一般情况下,指针指向一个对象,但是成员指针指示的是类的成员而非类的对象。类的静态成员不属于任何对象,因此无需特殊的执行静态成员的指针,指向静态成员的指针与普通指针没有区别。
成员指针的类型囊括了类的类型以及成员类型。但初始化一个这样的指针时,我们令其指向类的某一个成员,但是不指定该成员所属的对象;直到使用成员指针时,才提供成员所属的对象。
数据成员指针
和其它指针一样,在声明成员指针时我们也使用*来表示当前声明的名字是一个指针。与普通指针不同的是,成员指针还必须包含成员所属的类。因此我们必须在 * 之前添加classname:: 已表示当前定义的指针可以指向classname的成员。例如:
// pdata 可以指向一个常量(非常量)Student对下的string成员
string Student::*pdata;
上述语句将pdata声明成"一个指向Student类的string成员指针"。
如何使用数据成员指针
当我们初始化一个成员指针或者为成员指针赋值时,该指针并没有指向任何数据。成员指针指定了成员而非该成员所属的对象,只有当解引用成员指针时我们才提供对象信息。
与成员访问运算符 . 和 -> 类似,也有两种成员指针访问运算符: .* 和 ->* ,这两个运算符使得我们可以解引用指针并获得该对象的成员。例如:
Student student1,*pStudent = &student1;
// .*解引用pdata,已获得pdata所指的student1的对应成员
auto s = student1.*pdata;
//->*解引用pdata,已获得pdata所指的student1的对应成员
s = pStudent->*pdata;
成员函数指针
对于定义指向成员函数的指针,与指向数据成员的指针类似。我们使用classname::*的形式声明一个指向成员函数的指针。类似于任何其他函数指针,指向成员函数的指针也需要指定目标函数的返回值类型和形参列表。如果成员函数是const成员或者引用成员,则我们必须将const限定符或引用限定符包含进来。
和普通函数指针不同的是。在成员函数和指向该成员的指针之间不存在自动转换规则:
// TO-DO
// 需要补充实例
//必须显式地使用取地址运算符
如何使用成员函数指针
和使用指向数据成员的指针一样,我们使用 .* 或者 ->* 运算符作用于指向成员函数的指针以调用成员函数
/***
TO-DO 补充示例
**/
使用成员指针的类型别名
使用类别名或typedef可以让成员指针更容易理解
/**
TO-DO 补充示例
*/
总结
对于类的成员指针和普通的成员指针的差异,主要的区别是因为类的成员在通过实例化对象调用时编译器关联对应的this指针,这在后续的文章中会继续补充.