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的專欄