C++学习笔记二十二-类成员的指针
概述:成员指针只应用于类的非 static 成员。static 类成员不是任何对象的组成部分,所以不需要特殊语法来指向 static 成员,static 成员指针是普通指针。
一.定义数据成员的指针
1.对于类
class Screen { public: typedef std::string::size_type index; char get() const; char get(index ht, index wd) const; private: std::string contents; index cursor; index height, width; };
Screen 类的 contents 成员的类型为 std::string。contents 的完全类型是“Screen 类的成员,其类型是 std::string”。因此,可以指向 contents 的指针的完全类型是“指向 std::string 类型的 Screen 类成员的指针”,这个类型可写为: string Screen::*
2.可以用 contents 的地址初始化 ps_Screen,代码为
string Screen::*ps_Screen = &Screen::contents;
二、定义成员函数的指针
1.成员函数的指针必须在三个方面与它所指函数的类型相匹配:
a.函数形参的类型和数目,包括成员是否为 const。
b.返回类型。
c.所属类的类型。
2.例如指定 Screen 类的 const 成员函数的指针,不接受形参并返回 char 类型的值。这个 get 函数版本的指针可以像下面这样定义和初始化:
// pmf points to the Screen get member that takes no arguments char (Screen::*pmf)() const = &Screen::get;
3.调用操作符的优先级高于成员指针操作符,因此,包围 Screen::* 的括号是必要的,没有这个括号,编译器就将下面代码当作(无效的)函数声明:
// error: non-member function p cannot have const qualifier char Screen::*p() const;
三、使用类成员指针:
1.类似于成员访问操作符 . 和 ->,.* 和 -> 是两个新的操作符,它们使我们能够将成员指针绑定到实际对象。这两个操作符的左操作数必须是类类型的对象或类类型的指针,右操作数是该类型的成员指针。
2.成员指针解引用操作符(.*)从对象或引用获取成员。
3.成员指针箭头操作符(->*)通过对象的指针获取成员。
4.使用成员指针,可以这样调用不带形参的 get 函数版本:
// pmf points to the Screen get member that takes no arguments char (Screen::*pmf)() const = &Screen::get; Screen myScreen; char c1 = myScreen.get(); // call get on myScreen char c2 = (myScreen.*pmf)(); // equivalent call to get Screen *pScreen = &myScreen; c1 = pScreen->get(); // call get on object to which pScreen points c2 = (pScreen->*pmf)(); // equivalent call to get
5. 相同的成员指针操作符用于访问数据成员:
Screen::index Screen::*pindex = &Screen::width; Screen myScreen; // equivalent ways to fetch width member of myScreen Screen::index ind1 = myScreen.width; // directly Screen::index ind2 = myScreen.*pindex; // dereference to get width Screen *pScreen; // equivalent ways to fetch width member of *pScreen ind1 = pScreen->width; // directly ind2 = pScreen->*pindex; // dereference pindex to get width
5.因为调用操作符(())比成员指针操作符优先级高,所以调用 (myScreen.*pmf)() 和 (pScreen->*pmf)() 需要括号。