首頁 > 軟體

C++函數指標+物件指標+this指標+指向類靜態和非靜態成員的指標

2022-03-10 13:00:29

1、指向函數的指標

函數的程式碼在記憶體中的首地址,是由函數名錶示的,也就是說函數名等價於函數程式碼首地址。因此,可以定義一個指向函數的指標,即函數指標。函數指標定義和賦值的語法如下,其中資料型別代表指向函數的返回型別,形參表為指向函數的形參表;賦值時必須保證指向的函數名和函數指標的返回型別和形參完全相同:

資料型別 (*函數指標名)(形參表);
函數指標名 = 函數名;

下面的例子定義了一個函數和一個函數指標,通過函數指標呼叫函數程式碼:

/// 1、預先定義一個返回int型別的函數
int addOne(int x) {
    x = x + 1;
    return x;
}

/// 2、定義並賦值函數指標
int (*pointerAddOne)(int x);
pointerAddOne = addOne;

/// 3、使用函數指標和使用函數名的方式相同
data = pointerAddOne(data);

2、物件指標

顧名思義,物件指標表示指向物件的指標。物件名即物件的地址,所以可以將物件的地址賦值給同型別的指標,從而通過該指標使用此物件。

定義與使用物件指標包含4個步驟:

  • 定義XXX型別指標;
  • 定義XXX型別物件;
  • 將物件地址賦值給指標;
  • 使用“(*物件指標名).成員名”或者“物件指標名->成員名”的形式使用物件的成員;

下面的例子展示了物件指標的定義與使用:

Duck duck(666);
/// 定義並賦值物件指標
Duck *pointerDuck;
pointerDuck = &duck;
/// 物件指標採用兩種方式存取物件的成員
printf("%d n", (*pointerDuck).getAge());
printf("%d n", pointerDuck->getAge());

3、this指標

C++中,類的每個物件的資料成員都需要單獨分配記憶體,但是類的所有物件的函數成員共用記憶體。this指標是物件的非靜態成員函數的隱含引數,不需要自己進行定義,this指標指向當前呼叫非靜態成員函數的物件。當類物件呼叫非靜態成員函數時,物件的地址作為this指標的值,進而非靜態成員函數通過this指向的地址,來存取物件的資料成員(類的不同物件的資料成員儲存在不同的地址,this指標用於傳遞物件的地址)。

this指標存取其指向的物件資料成員的語法為:

this->資料成員名

下面的例子中,Duck類的成員函數getAge需要存取物件的資料成員duckAge,但是由於函數中已經存在同名的duckAge變數,所以需要通過this來存取資料成員duckAge

class Duck{
public:
    Duck(int age) { duckAge = age; };
    int getAge() { 
        int duckAge = 3;
            /// 通過this存取物件的資料成員duckAge,而不是區域性變數duckAge
        return this->duckAge; 
    };
private:
    int duckAge;
};

4、指向類的非靜態成員的指標

首先,類的靜態成員和非靜態成員是不同的,靜態成員屬於類,而非靜態成員屬於物件。指向類的非靜態成員的指標,包含指向資料成員的指標和指向函數成員的指標。宣告時需要指明指標指向的“類名”和“型別”,型別表示資料成員或函數成員的資料型別:

型別 類名::*資料成員指標名;
型別 (類名::*函數成員指標名)(參數列);

下面定義的Duck類包含public成員:int型別資料成員duckWeight和int型別函數成員getAge()(指向非靜態成員的指標也必須遵守存取許可權,不能指向private成員)下面分別宣告指向二者的指標:

int Duck::*pointerDuckWeight;
int (Duck::*pointerGetAge)();

指向非靜態成員的資料指標和函數指標賦值語法為:

資料成員指標名 = &類名::資料成員名;
函數成員指標名 = &類名::函數成員名;
下面對兩個指標進行賦值:

pointerDuckWeight = &Duck::duckWeight;
pointerGetAge = &Duck::getAge;

上面進行的宣告和賦值都是針對類進行的,所以並沒有指向物件的成員地址。這裡涉及到類的定義過程,類定義時並沒有分配記憶體,而只是確定各個資料成員所佔記憶體大小和相對位置。所以,可以使用物件的起始地址加相對位置對資料成員進行存取。非靜態資料成員指標存取成員的語法有如下兩種方式:

物件名.*資料成員的指標名
物件指標名->*資料成員指標名

/// 呼叫例子
printf("%d n", duck.*pointerDuckWeight);

函數成員並不針對每個物件都有一個副本,而是共用的。物件呼叫函數成員時需要通過this指標,非靜態成員函數指標的呼叫包含下面兩種語法:

(物件名.函數成員指標名)(實參表)
(物件指標名->*函數成員指標名 )(實參表)

/// 實際呼叫的例子
printf("%d n", (duck.*pointerGetAge)());

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

對於類的靜態資料成員和函數成員,由於其並不屬於具體的物件,所以只需要普通的資料型指標和函數型指標即可。

下面定義的Duck類包含用static宣告的靜態資料成員和靜態函數成員:

class Duck{
public:
    static int getAge() { 
        return 666;
    };
    static int duckWeight;
};
int Duck::duckWeight = 333;

下面是指向類的靜態成員的資料型指標和函數型指標的定義和賦值過程:

int *pointerDuckWeight;
int (*pointerGetAge)();
/// 賦值語法:指標名=&類名:靜態成員名
pointerDuckWeight = &Duck::duckWeight;
pointerGetAge = &Duck::getAge;

呼叫指標的時候,只需要遵守基本資料型指標和函數型指標的呼叫語法即可:

printf("%d n", *pointerDuckWeight);
printf("%d n", (*pointerGetAge)());

到此這篇關於C++函數指標+物件指標+this指標+指向類靜態和非靜態成員的指標的文章就介紹到這了,更多相關C++指標內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com