第18章 特殊工具与技术(9)
18.3 类成员的指针
成员指针只应用于类的非static成员。static类成员不是任何对象的组成部分,所以不需要特殊语法来指向static成员,static成员指针是普通指针。
18.3.1 声明成员指针
1.定义数据成员的指针
class Screen1{
public:
typedef std::string::size_type index;
char get() const;
char get(index ht,index wd)const;
std::string contents;
index cursor;
index height,width;
};
string Screen1::*ps_Screen;
ps_Screen=&Screen1::contents;
Screen1::index Screen1::*pindex;
pindex=&Screen1::width;
class Screen1{
public:
typedef std::string::size_type index;
char get() const;
char get(index ht,index wd)const;
std::string contents;
index cursor;
index height,width;
};
string Screen1::*ps_Screen;
ps_Screen=&Screen1::contents;
Screen1::index Screen1::*pindex;
pindex=&Screen1::width;2. 定义成员函数的指针
成员函数的指针必须在三个方面与它所指函数的类型相匹配:
(1) 函数形参的类型与数目,包括成员是否为const。
(2) 返回类型。
(3) 所属类的类型。
通过指定函数返回类型、形参表和类来定义成员函数的指针。
char (Screen1::*method1)() const;
method1=&Screen1::get;
char (Screen1::*method1)() const;
method1=&Screen1::get;调用操作符的优先级高于成员指针操作符,因此,包围Screen::*的括号是必要的,没有这个括号,编译器就将下面代码当作(无效的)函数声明。
char Screen1::*method1() const;
char Screen1::*method1() const;3. 为成员指针使用类型别名
类型别名(typedef)可以使成员指针更容易阅读。
typedef char (Screen1::*p)(Screen1::index,Screen1::index) const;
p method1=&Screen1::get;
typedef char (Screen1::*p)(Screen1::index,Screen1::index) const;
p method1=&Screen1::get;可以使用成员指针函数类型来声明函数形参和函数返回类型。
typedef char (Screen1::*p)(Screen1::index,Screen1::index) const;
p method2=&Screen1::get;
typedef char (Screen1::*p)(Screen1::index,Screen1::index) const;
p method2=&Screen1::get;Screen1& action(Screen1&, p=&Screen1::get);
Screen1 myScreen;
action(myScreen);
action(myScreen,method2);
action(myScreen,&Screen1::get);
Screen1& action(Screen1&, p=&Screen1::get);
Screen1 myScreen;
action(myScreen);
action(myScreen,method2);
action(myScreen,&Screen1::get);18.3.2 使用类成员的指针
类似于成员访问操作符.和->,.*和->*是两个新的操作符,它们使我们能够将成员指针绑定到实际对象。这两个操作符的左操作数必须是类类型的对象或类类型的指针,右操作数是该类型的成员指针。
成员指针解引用操作符(.*)从对象或引用获取成员。
成员指针箭头操作符(->*)通过对象的指针获取成员。
1. 使用成员函数的指针
char (Screen1::*method1)() const;
method1=&Screen1::get;
Screen1 myScreen=Screen1();
myScreen.get();
(myScreen.*method1)();
Screen1 *pscreen1=&myScreen;
pscreen1->get();
(pscreen1->*method1)();
char (Screen1::*method1)() const;
method1=&Screen1::get;
Screen1 myScreen=Screen1();
myScreen.get();
(myScreen.*method1)();
Screen1 *pscreen1=&myScreen;
pscreen1->get();
(pscreen1->*method1)();因为调用操作符(())比成员指针操作符优先级高,所以调用成员函数指针需要括号。
像其他任何函数一样,也可以通过成员函数指针进行的调用中传递实参:
char (Screen1::*method1)(Screen1::index,Screen1::index) const;
method1=&Screen1::get;
Screen1 myScreen=Screen1();
myScreen.get(10,20);
(myScreen.*method1)(10,20);
char (Screen1::*method1)(Screen1::index,Screen1::index) const;
method1=&Screen1::get;
Screen1 myScreen=Screen1();
myScreen.get(10,20);
(myScreen.*method1)(10,20);2. 使用数据成员的指针
Screen1::index Screen1::*pindex;
pindex=&Screen1::width;
Screen1 myScreen=Screen1();
myScreen.*pindex=10;
Screen1::index Screen1::*pindex;
pindex=&Screen1::width;
Screen1 myScreen=Screen1();
myScreen.*pindex=10;3. 成员指针函数表
class Screen2{
public:
Screen2& home();
Screen2& forward();
Screen2& back();
Screen2& up();
Screen2& down();
};
class Screen2{
public:
Screen2& home();
Screen2& forward();
Screen2& back();
Screen2& up();
Screen2& down();
};4. 使用函数指针表
class Screen2{
public:
Screen2& home();
Screen2& forward();
Screen2& back();
Screen2& up();
Screen2& down();
typedef Screen2& (Screen2::*Method)();
static Method Menu[];
public:
enum Directions{HOME,FORWARD,BACK,UP,DOWN};
Screen2& move(Directions);
};
Screen2& Screen2::move(Directions cm)
{
(this->*Menu[cm])();
return *this;
}
Screen2 myScreen2;
myScreen2.move(Screen2::HOME);
class Screen2{
public:
Screen2& home();
Screen2& forward();
Screen2& back();
Screen2& up();
Screen2& down();
typedef Screen2& (Screen2::*Method)();
static Method Menu[];
public:
enum Directions{HOME,FORWARD,BACK,UP,DOWN};
Screen2& move(Directions);
};
Screen2& Screen2::move(Directions cm)
{
(this->*Menu[cm])();
return *this;
}
Screen2 myScreen2;
myScreen2.move(Screen2::HOME);5. 定义成员函数指针表
Screen2::Method Screen2::Menu[]={
&Screen2::home,
&Screen2::forward,
&Screen2::back,
&Screen2::up,
&Screen2::down,};
摘自 xufei96的专栏
补充:软件开发 , C++ ,