詳解C++中的成員訪問(wèn)運(yùn)算符和指針到成員運(yùn)算符
成員訪問(wèn)運(yùn)算符:. 和 ->
語(yǔ)法
postfix-expression
. name
postfix-expression –> name
備注
成員訪問(wèn)運(yùn)算符 . 和 -> 用來(lái)引用結(jié)構(gòu)、聯(lián)合和類的成員。成員訪問(wèn)表達(dá)式具有選定成員的值和類型。
有兩種形式的成員訪問(wèn)表達(dá)式:
在第一種形式中,postfix-expression 表示結(jié)構(gòu)、類或聯(lián)合類型的值,name 為指定的結(jié)構(gòu)、聯(lián)合或類的成員命名。運(yùn)算的值是 name 的值且為左值(如果 postfix-expression 是左值)。
在第二種形式中,postfix-expression 表示指向結(jié)構(gòu)、聯(lián)合或類的指針,name 為指定的結(jié)構(gòu)、聯(lián)合或類的成員命名。該值是 name 的值且是左值。 –> 運(yùn)算符取消引用該指針。因此,表達(dá)式 e–>member 和 (*e).member(其中,e 表示指針)會(huì)產(chǎn)生相同的結(jié)果(重載運(yùn)算符 –> 或 * 的情況除外)。
以下示例演示成員訪問(wèn)運(yùn)算符的兩種形式。
// expre_Selection_Operator.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
struct Date {
Date(int i, int j, int k) : day(i), month(j), year(k){}
int month;
int day;
int year;
};
int main() {
Date mydate(1,1,1900);
mydate.month = 2;
cout << mydate.month << "/" << mydate.day
<< "/" << mydate.year << endl;
Date *mydate2 = new Date(1,1,2000);
mydate2->month = 2;
cout << mydate2->month << "/" << mydate2->day
<< "/" << mydate2->year << endl;
delete mydate2;
}
這樣的話出來(lái)的兩個(gè)值分別為:
2/1/1900 2/1/2000
指針到成員運(yùn)算符:.* 和 ->*
語(yǔ)法
expression .* expression
expression –>* expression
備注
指向成員的指針運(yùn)算符(.* 和 –>*)返回表達(dá)式左側(cè)上指定的對(duì)象的特定類成員的值。右側(cè)必須指定該類的成員。下面的示例演示如何使用這些運(yùn)算符:
// expre_Expressions_with_Pointer_Member_Operators.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class Testpm {
public:
void m_func1() { cout << "m_func1\n"; }
int m_num;
};
// Define derived types pmfn and pmd.
// These types are pointers to members m_func1() and
// m_num, respectively.
void (Testpm::*pmfn)() = &Testpm::m_func1;
int Testpm::*pmd = &Testpm::m_num;
int main() {
Testpm ATestpm;
Testpm *pTestpm = new Testpm;
// Access the member function
(ATestpm.*pmfn)();
(pTestpm->*pmfn)(); // Parentheses required since * binds
// less tightly than the function call.
// Access the member data
ATestpm.*pmd = 1;
pTestpm->*pmd = 2;
cout << ATestpm.*pmd << endl
<< pTestpm->*pmd << endl;
delete pTestpm;
}
Output
m_func1
m_func1
結(jié)果分別為:
1 2
在前面的示例中,指向成員的指針 pmfn 用于調(diào)用成員函數(shù) m_func1。另一個(gè)指向成員的指針 pmd 用于訪問(wèn) m_num 成員。
二元運(yùn)算符 .* 將其第一操作數(shù)(必須是類類型的對(duì)象)與其第二操作數(shù)(必須是指向成員的指針類型)組合在一起。
二元運(yùn)算符 –>* 將其第一操作數(shù)(必須是指向類類型的對(duì)象的指針)與其第二操作數(shù)(必須是指向成員的指針類型)組合在一起。
在包含 .* 運(yùn)算符的表達(dá)式中,第一操作數(shù)必須是類類型且可訪問(wèn),而指向第二操作數(shù)中指定的成員的指針或可訪問(wèn)類型的成員的指針明確從該類派生并且可供該類訪問(wèn)。
在包含 –>* 運(yùn)算符的表達(dá)方式中,第一操作數(shù)必須是第二操作數(shù)中指定的類型的“指向類類型的指針”或明確地從該類派生的類型。
考慮以下類和程序段:
// expre_Expressions_with_Pointer_Member_Operators2.cpp
// C2440 expected
class BaseClass {
public:
BaseClass(); // Base class constructor.
void Func1();
};
// Declare a pointer to member function Func1.
void (BaseClass::*pmfnFunc1)() = &BaseClass::Func1;
class Derived : public BaseClass {
public:
Derived(); // Derived class constructor.
void Func2();
};
// Declare a pointer to member function Func2.
void (Derived::*pmfnFunc2)() = &Derived::Func2;
int main() {
BaseClass ABase;
Derived ADerived;
(ABase.*pmfnFunc1)(); // OK: defined for BaseClass.
(ABase.*pmfnFunc2)(); // Error: cannot use base class to
// access pointers to members of
// derived classes.
(ADerived.*pmfnFunc1)(); // OK: Derived is unambiguously
// derived from BaseClass.
(ADerived.*pmfnFunc2)(); // OK: defined for Derived.
}
指向成員的指針運(yùn)算符 .* 或 –>* 的結(jié)果是在指向成員的指針的聲明中指定的類型的對(duì)象或函數(shù)。因此,在前面的示例中,表達(dá)式 ADerived.*pmfnFunc1() 的結(jié)果是指向返回 void 的函數(shù)的指針。如果第二操作數(shù)是左值,則此結(jié)果為左值。
System_CAPS_note注意
如果某個(gè)指向成員的指針運(yùn)算符的結(jié)果是函數(shù),則該結(jié)果只能用作函數(shù)調(diào)用運(yùn)算符的操作數(shù)。
相關(guān)文章
C語(yǔ)言運(yùn)算符的優(yōu)先級(jí)和結(jié)合性實(shí)例詳解
本文主要介紹C語(yǔ)言運(yùn)算符的知識(shí),這里對(duì)運(yùn)算符的優(yōu)先級(jí)和結(jié)合性做出了詳解,并附實(shí)例代碼,希望能幫助有需要的小伙伴2016-07-07
淺析c#中如何在form的webbrowser控件中獲得鼠標(biāo)坐標(biāo)
以下是對(duì)c#中如何在form的webbrowser控件中獲得鼠標(biāo)坐標(biāo)的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下2013-07-07
C/C++中一次性執(zhí)行多個(gè)DOS命令的實(shí)現(xiàn)思路
在C語(yǔ)言中執(zhí)行DOS命令的方法很多,在這就不一給大家一一介紹了,本文重點(diǎn)給大家介紹C/C++中一次性執(zhí)行多個(gè)DOS命令的實(shí)現(xiàn)思路,需要的朋友參考下2017-12-12
C++簡(jiǎn)單集合類的實(shí)現(xiàn)方法
如何使用C++實(shí)現(xiàn)一個(gè)簡(jiǎn)單的集合類,這篇文章主要介紹了C++簡(jiǎn)單集合類的實(shí)現(xiàn)方法,感興趣的小伙伴們可以參考一下2016-07-07
學(xué)習(xí)C和C++的9點(diǎn)經(jīng)驗(yàn)總結(jié)
本文給大家總結(jié)了一下我們?cè)趯W(xué)習(xí)C和C++的時(shí)候的一些經(jīng)驗(yàn)和需要注意的事項(xiàng),希望能給大家一些幫助,少走些彎路2015-12-12
OpenCV使用BSM統(tǒng)計(jì)視頻中移動(dòng)的對(duì)象
這篇文章主要為大家詳細(xì)介紹了OpenCV如何使用BackgroundSubstractor(BSM)實(shí)現(xiàn)視頻中移動(dòng)對(duì)象統(tǒng)計(jì)功能,文中的示例代碼講解詳細(xì),需要的可以參考一下2023-02-02
為什么說(shuō)C語(yǔ)言是永不過(guò)時(shí)的語(yǔ)言
時(shí)隔5年,C語(yǔ)言再次領(lǐng)先Java,榮登TIOBE編程語(yǔ)言排行榜第一,那么C語(yǔ)言為何不會(huì)過(guò)時(shí)?你需要掌握多少種語(yǔ)言呢,感興趣的朋友通過(guò)本文一起學(xué)習(xí)下吧2020-11-11

