指向類的成員的指標

2021-06-03 19:08:03 字數 4222 閱讀 7282

分類: c++基礎

2011-08-09 14:57

25人閱讀收藏 

舉報指向類的成員的指標

分為指向類的資料成員和成員函式的指標。

指向資料成員的指標格式如下:

《型別說明符》《類名》::*《指標名》

指向成員函式的指標格式如下:

《型別說明符》(《類名》::*《指標名》)(《參數列》)

例如,設有如下一

個類a:

[cpp]view plain

copy

class

a    

a(int

i)   

intc;  

private

:  int

a;  

};  

定義乙個指向類a的資料成員c的指標pc,其格式如下:

int a:: *pc = &a::c;

再定義乙個指向類a的成員函式fun的指標pfun,其格式如下:

int (a:: *pfun)(int) = a::fun;

由於類不是執行時存在的物件。因此,在使用這類指標時,需要首先指定a類的乙個物件,然後,通過物件來引用指標所指向的成員。例如,給pc指標所指向的資料成員c賦值8,可以表示如下:

[cpp]view plain

copy

a a;  

a.*pc = 8;  

其中,運算子.*是用來對指向類成員的指標來操作該類的物件的。

如果使用指向物件的指標來對指向類成員的指標進行操作時,使用運算子->*。例如:

[cpp]view plain

copy

a *p = &a;  

p->*pc = 8;"font-family: arial, verdana, sans-serif; white-space: normal; font-size: 12.0563px; "

>  

指向類的資料成員的指標並非指標,因為它既不包含位址,行為也不像指標。

與常規指標不同,乙個指向成員的指標並不指向乙個具體的記憶體位置,它指向的是乙個類的特定成員,而不是指向乙個特定物件裡的特定成員。通常最清晰的做法是將指向資料成員的指標看作為乙個偏移量。

c++標準並沒有說該如何實現指向成員的指標,

大多數編譯器都將指向資料成員的指標實現為乙個整數,其中包含被指向成員的偏移量。另外加上1(加1是為了讓0值可以表示乙個空的資料成員指標)。這個偏移量告訴你,乙個特定成員的位置距離物件的起點有多少個位元組。

乙個類成員的偏移量在任何物件中都是相同的。

給定乙個成員在類內的偏移量,為了訪問位於那個偏移量的資料成員,我們需要該類的乙個物件的位址。這時候就需要 .* 和 ->* 這兩個看上去非同尋常的操作符閃亮登場了。

[cpp]view plain

copy

class

c   

;    

intc::*pimc; 

// 乙個指標,指向c的乙個int成員  

c ac;    

c* pc = ∾    

pimc = &c::a_; //::的優先順序高於&  

ac.*pimc = 0;    

intb = pc -> *pimc;  

當寫下pc->*pimc時,其實是請求將pc內的位址加上pimc內的偏移量,

為的是訪問pc所指向的c物件中適當的資料成員。

當寫ac.*pimc時,是在請求ac的位址加上pimc中的偏離量,

也是為了訪問pc所指向的c物件中適當的資料成員。

另外,存在從指向基類成員的指標到指向公有派生類成員的指標的隱式轉換,但不存在從指向派生類成員的指標到指向其任何乙個基類成員的指標的轉換(

基類指標可轉換為子類指標,反之則不行

)。這個可以從

c++物件的記憶體布局

來理解,因為

基類成員一般在子類物件的前部分,所以這些成員在基類或者子類中的偏移是一樣的;解析的時候,就是物件的首位址加上這個偏移量來獲得真正的資料成員。

理解了這一點,你就知道有虛繼承的類中,與虛基類的相關轉化是非法的。

讓我們再看看指向一般函式的指標的定義格式:

《型別說明符》*《指向函式指標名》(《參數列》)

關於給指向函式的指標賦值的格式如下:

《指向函式的指標名》=《函式名》

關於在程式中,使用指向函式的指標呼叫函式的格式如下:

(*《指向函式的指標名》)(《實參表》)

如果是指向類的成員函式的指標還應加上相應的物件名和物件成員運算子。

下面給出乙個使用指向類成員指標的例子:

[cpp]view plain

copy

#include 

class

a    

intfun(

intb)   

intc;  

private

:  int

a;  

};  

intmain()    

以上程式定義了好幾個指標,雖然它們都是指標,但是所指向的物件是不同的。p是指向類的物件;pc是指向類的資料成員;pfun是指向類的成員函式。因此它們的值也是不相同的。

物件指標和物件引用作函式的引數

1.物件指標作函式的引數

使用物件指標作為函式引數要比使用物件作函式引數更普遍一些。因為使用物件指標作函式引數有如下兩點好處:

(1) 

實現傳址呼叫。可在被呼叫函式中改變呼叫函式的引數物件的值,實現函式之間的資訊傳遞。

(2) 

使用物件指標實參僅將物件的位址值傳給形參,而不進行副本的拷貝,這樣可以提高執行效率,減少時空開銷。

[cpp]view plain

copy

#include 

using

namespace

std;  

class

m    

m(int

i, int

j)   

void

copy(m *m);  

void

setxy(

inti, 

intj)   

void

print() ;  

void

m::copy(m *m)  

void

fun(m m1, m *m2);  

intmain()  

void

fun(m m1, m *m2)    

5, 7

22, 25

從輸出結果可以看出,當在被呼叫函式fun中,改變了物件的資料成員值[m1.setxy(12, 15)]和指向物件指標的資料成員值[m2->setxy(22, 25)]以後,可以看到只有指向物件指標作引數所指向的物件被改變了,而另乙個物件作引數,形參物件值改變了,可實參物件值並沒有改變。因此輸出上述結果。

2. 物件引用作函式引數

在實際中,使用物件引用作函式引數要比使用物件指標作函式更普遍,這是因為使用物件引用作函式引數具有用物件指標作函式引數的優點,而用物件引用作函式引數將更簡單,更直接。所以,在c++程式設計中,人們喜歡用物件引用作函式引數。現舉一例子說明物件引用作函式引數的格式。

[cpp]view plain

copy

#include 

using

namespace

std;  

class

m    

m(int

i, int

j)   

void

copy(m &m);  

void

setxy(

inti, 

intj)   

void

print() ;  

void

m::copy(m &m)  

void

fun(m m1, m &m2);  

intmain()  

void

fun(m m1, m &m2)  

該例子與上面的例子輸出相同的結果,只是呼叫時的引數不一樣。

指向類成員的指標

一 指向類的普通成員的指標 非靜態 1 指向類成員函式的指標 簡單的講,指向類成員函式的指標與普通函式指標的區別在於,前者不僅要匹配函式的引數型別和個數以及返回值型別,還要匹配該函式指標所屬的類型別。總結一下,比較以下幾點 a 引數型別和個數 b 返回值型別 c 所屬的類型別 特別之處 究其原因,是...

指向類成員的指標

前面曾寫過一篇惱人的函式指標 一 總結了普通函式指標的宣告 定義以及呼叫,還有函式指標陣列,函式指標用作返回值等。但是作為c 的研讀,我發現我漏掉了乙個最重要的內容,就是指向類成員的指標,這裡將做相應補充 相關 測試環境為vs 2010 指向類成員的指標總的來講可以分為兩大類四小類 指向資料成員還是...

指向類成員的指標

在c 語言中,可以定義乙個指標,使其指向類成員或成員函式,然後通過指標來訪問類的成員。這包括指向屬性成員的指標和指向成員函式的指標。指向非靜態資料成員的指標在定義時必須和類相關聯,在使用時必須和具體的物件關聯。由於類不是執行時存在的物件。因此,在使用這類指標時,需要首先指定類的乙個物件,然後,通過物...