惱人的函數指標(二),惱人函數指標

來源:互聯網
上載者:User

惱人的函數指標(二),惱人函數指標

原文連結:http://www.cnblogs.com/AnnieKim/archive/2011/12/04/2275589.html

前面曾寫過一篇惱人的函數指標(一),總結了普通函數指標的聲明、定義以及調用,還有函數指標數組,函數指標用作返回值等。但是作為C++的研讀,我發現我漏掉了一個最重要的內容,就是指向類成員的指標,這裡將做相應補充(相關代碼測試環境為vs 2010)。

指向類成員的指標總的來講可以分為兩大類四小類(指向資料成員還是成員函數,指向普通成員還是靜態成員),下面一一做介紹:

一、指向類的普通成員的指標(非靜態)

1、指向類成員函數的指標

簡單的講,指向類成員函數的指標與普通函數指標的區別在於,前者不僅要匹配函數的參數類型和個數以及返

回值類型,還要匹配該函數指標所屬的類類型。總結一下,比較以下幾點:

a)參數類型和個數

b)返回值類型

c)所屬的類類型(特別之處)

究其原因,是因為非靜態成員函數必須被綁定到一個類的對象或者指標上,才能得到被調用對象的this指標,

然後才能調用指標所指的成員函數(我們知道,所有類的對象都有自己資料成員的拷貝,但是成員函數都是共

用的,為了區分是誰調用了成員函數,就必須有this指標,this指標是隱式的添加到函數參數列表裡去的)。

明白了這點,接下來就簡單了。

聲明:與普通函數作為區分,指向類的成員函數的指標只需要在指標前加上類類型即可,格式為:

typedef 返回值 (類名::*指標類型名)(參數列表);

賦值:只需要用類的成員函數地址賦值即可,格式為:

指標類型名  指標名 = &類名::成員函數名;

注意:這裡的這個&符號是比較重要的:不加&,編譯器會認為是在這裡調用成員函數,所以需要給出參數列

表,否則會報錯;加了&,才認為是要擷取函數指標。這是C++專門做了區別對待。

調用:調用方法也很簡單,針對調用的對象是對象還是指標,分別用.*和->*進行調用,格式為:

(類對象.*指標名)(參數列表);

(類指標->*指標名)(參數列表);

(既然是指標, 不管是資料類型的指標, 還是函數指標, 不管是普通函數指標還是類函數成員指標, 都應該按照

習慣加一個&去取地址符, 不過對於普通函數, 編譯器做了特殊的處理, 不過我本人認為會讓人誤解, 所有東

西, 涉及到類的, 基本上都會有個類域; 當應引用指標的值的時候, 我們應該和普通的指標一樣, 用*去引用

符。提醒一下大家, 因為類的.和->運算子的優先順序都高於去引用符*, 所以上面的能那麼些, 不清楚的讀者可

以做自己看看運算子的優先順序.)

注意:這裡的前面一對括弧是很重要的,因為()的優先順序高於成員操作符指標的優先順序。

下面舉個簡單的例子就一目瞭然了:

class A;typedef void (A::*NONSTATICFUNCPTR)(int);    //typedef class A{public:    void NonStaticFunc(int arg)    {        nonStaticMember = arg;        cout << nonStaticMember << endl;    }private:    int    nonStaticMember;}; int main(){    NONSTATICFUNCPTR funcPtr = &A::NonStaticFunc;     A a;    (a.*funcPtr)(10);        //通過對象調用     A *aPtr = new A;    (aPtr->*funcPtr)(10);    //通過指標調用     return 0;}

2、指向類資料成員的指標

成員函數搞懂了,資料成員也就easy了,只要判斷以下兩點是否一致即可:

a)資料成員類型

b)所屬的類類型

另外,聲明、賦值還有調用方法等這些是和前面類似的,再舉個例子吧:

class A;typedef int(A::*NONSTATICDATAPTR);        //typedef class A{public:    A(int arg) :nonStaticMember(arg){}    int    nonStaticMember;}; int main(){    NONSTATICDATAPTR dataPtr = &A::nonStaticMember;     A a(10);    cout << a.*dataPtr;        //通過對象引用     A *aPtr = new A(100);    cout << aPtr->*dataPtr;    //通過指標引用     return 0;}

運行結果,當然是各自輸出10和100啦。

二、指向類的靜態成員的指標

類的靜態成員和普通成員的區別在於,他們是不依賴於具體對象的,所有執行個體化的對象都共用同一個靜態成員,

所以靜態成員也沒有this指標的概念。所以,指向類的靜態成員的指標就是普通的指標。

看下面的例子就明白了:

typedef const int *STATICDATAPTR;typedef int(*STATICFUNCPTR)();        //跟普通函數指標是一樣的 class A{public:    static int StaticFunc() { return staticMember; };    static const int staticMember = 10;}; int main(){    STATICDATAPTR dataPtr = &A::staticMember;    STATICFUNCPTR funcPtr = &A::StaticFunc;     cout << *dataPtr;            //直接解引用    cout << (*funcPtr)();     return 0;}

最後註明一下,顯然的,要使用(&類名::成員名)擷取指向成員的指標,首先這個成員必須是對外可見的哦,即public的,不然是沒有許可權擷取的^^。


寫到此,簡單總結一下就是:

1)靜態和普通的函數指標沒啥區別;

2)非靜態加一個類局限一下即可。

 

不知道以後還會不會有函數指標相關的內容,先到此完結吧。

有錯誤歡迎指正,我會及時修改^^。

(完)




函數指標與指標的不同在什地方?

指標是C語言的一種資料類型;
函數指標是C指標的一種。

問“函數指標與指標的區別在哪裡?” 說明LZ對指標還不慎瞭解。修改一下你的問題:
“函數指標與整型指標的區別在哪裡?”
這樣的話,我就告訴你:
1. 二者都是指標
2. 函數指標裡存放的是一個函數的首地址,而整型指標裡放的是一個整型變數的地址;
3.指標本身是參考型別。所以使用時都要解除引用。函數指標與整型指標解除引用的方式不同。整型指標有兩種方式解除引用:
如對整型指標pi:
int i = 0;
int *pi = &i;
解除引用方法一: *pi
解除引用方法二: pi[0]
對函數指標pf:
int f(int);
int (*pf)(int) = f ;
解除引用方法: pf(8);

整型指標解除引用方法二: pi[0]更像數組。也更像函數指標解除引用的方法,原因是:
數組名、和函數名 的本質都是地址。指標的本質也是地址。
4。從以上例子中看到賦值形式不同
函數指標 pf = f; (不用 &。其實用也一樣)
整型指標 pi = &i;
原因是數組名、和函數名 的本質都是地址,而整型變數的本質(當作為左值【如果允許】或右值時)是地址裡的值。
5. 對函數指標,一般不可以做遞增操作 如:pf++ 99.9999%會崩潰
如果要訪問函數陣列,需要使用函數指標數組
 
怎用函數指標做參數?

首先,聲明函數指標的類型是這樣聲明的:
void (*pFun)(int,int)
void 這個函數傳回值的類型,pFun 這個指標的名稱,(int x,int y) 這個函數的參數列表。
第二,函數名就是函數指標,如有如下函數
void hello()
{
printf("hello world!\n");
}
那hello就是這個函數的指標。
第三,實際例子:
#include<cstdio>

void hello(){
printf("hello world!\n");
}

void runFun(void (*pFun)()){
pFun();
}
void main()

{
runFun(hello);
}
首先,定義hello函數。
第二,定義runFun函數,這個函數的參數是一個 函數指標,上面已經說過定義方法,runFun直接使用傳過來的 函數指標 執行函數。
第三,在main中將hello函數的指標(即hello)傳進runFun。
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.