(一三一)指向物件的指標

2021-07-09 18:12:11 字數 4197 閱讀 4681

類物件也可以像基本型別那樣,使用指標。

假如有man

類的物件

a,可以使用指標指向它:

man* c=&a;

這裡表示指標c

(型別為

man)指向物件

a的位址(使用位址運算子&)。

也可以使用new

:man *a=new man;

這是new

乙個動態記憶體位址,型別為

man,然後用

a指向位址。

new的過程中,呼叫預設建構函式建立乙個物件,被放在堆,而指標

a指向的則是這個物件的位址。

關於析構函式的呼叫:

①當離開物件的作用域時,析構函式將被呼叫(例如**塊內宣告的物件,在離開**塊時);

②靜態物件,將在程式執行完畢時,呼叫靜態物件的析構函式(main()函式結束);

③new

出來的物件,只在使用

delete

時,呼叫物件的析構函式。

當指標遇見物件時的幾種情況:

假設類為man

,已宣告物件

man one

(注,已被初始化賦值);

①man *a;

乙個普通的man

型別指標,尚未指向任何物件

②man *a=&one;

指標指向物件one

的位址。

③man *a = new man;

指標使用new

申請動態記憶體建立新的

man物件,呼叫

man的 

預設建構函式 。

④man *a = new man(one);

指標使用new

申請動態記憶體建立新物件,並同時以物件

one為引數進行初始化,呼叫

man的 

複製建構函式 。

⑤man *a = new man[5];

指標指向動態陣列,陣列型別為man

,元素個數為

5,並且每個都呼叫 

預設建構函式 進行初始化。

⑥man *a = new man("aabbcc");

指標new

乙個物件,這個物件用引數"aabbcc"進行初始化(假如有多個引數的話,可以用例如 (1,"aabbcc") 這樣。呼叫 建構函式 。

當類指標呼叫類函式方法時:

已知,結構指標可以通過 -> 運算子來訪問結構成員,也可以通過 (*結構物件).結構成員 來訪問。類的指標也類似。

例如:man*a = new

man(1,"abc");

(*a).show(); //辦法一

a->show(); //辦法二

這兩個的效果,是一樣的。

new定位運算子:

已知,new

定位運算子的效果是,使用某個指定位址的記憶體。

前提一:需要使用標頭檔案

使用int

型別變數的位址)

前提三:程式設計師需要為這種使用負責(不會像new

那樣在堆中自動申請夠足夠的動態記憶體)

作用:

根據我搜尋的一些內容顯示,new

定位運算子的作用有(有些意思可能是相互重複的):

①在特定位址呼叫建構函式

建構函式和析構函式的指標是無法獲得的,

那麼怎麼單純的呼叫建構函式呢,這時候定位new

就有用了

②硬體程式設計

如果知道了硬體裝置的位址,

想要將那個硬體裝置與乙個

c++類直接關聯

,那麼定位

new就非常有效了

③實現基礎庫

基礎庫一般為了效率要先預分配記憶體,

然後在預分配的記憶體上執行構造

,幾乎所有的

c++容器(有10

種,但我尚沒搞懂是什麼

)都用到了定位new

④在先分配好的緩衝區中劃分出一部分用作我們自己的記憶體規劃。例如先new char[40]

,然後在這40個

char

寬度的記憶體中,再自行使用。

⑤在特定位置建立物件。

,很可能會覆蓋之前的資料。

大概就是以上作用。

配對:

new可以和

delete

,也需要和

delete

配對使用;

但是new

定位運算子,不能和

delete

配對使用。

快取區:

大概意思就是預先準備的一部分記憶體,

例如new char[80]

就是80

個char

寬度的記憶體,在未被

delete

前都不會被占用。

也可能是char a[80]

,這部分就在棧區了。

有點劃地盤的感覺。

析構函式:

使用new

定位運算子建立的物件,不應使用

delete/delete,

原因在於,new

定位運算子一般被放在緩衝區之中(緩衝區有可能的是使用

new xx

申請的,但也有可能是在棧、或者靜態儲存區),這可能導致錯誤。

對於使用new

定位運算子建立的物件,應該 

顯式的使用析構函式 。

這也是需要顯式使用析構函式的少數幾種情形之一。

因為是指標,所以要注意運算子。例如:one->~man();

關於使用順序,晚建立的物件(使用new

定位運算子,特別是在同一位址),應該先呼叫析構函式(

因為晚建立的物件,可能依賴於早建立的,不過不懂這句話),早建立的後呼叫析構函式。(有點類似棧的lifo)

之所以必須顯式的呼叫析構函式,因為假如不顯示呼叫析構函式的話,那麼類物件則不會被銷毀(就像使用new

的物件一樣,不受**塊結束所限制,只有使用了

delete

才會被呼叫析構函式而銷毀)。

防止覆蓋:

假如已經在快取區內某個記憶體位址(one)使用new

定位運算子建立了乙個物件

a,然後又想在這個快取區內置立乙個物件

b,但不想讓

b覆蓋物件

a。那麼就應該使用運算子

sizeof()。

運算子sizeof

的作用是返回物件的記憶體寬度,例如

cout <<

sizeof(*b) << endl;

cout <<

sizeof(man) << endl;

這二者貌似差不多,不過書上用的是後者。

問題:這二者有區別麼?

而在防止覆蓋時,是這麼使用的:

man*b = new(one + sizeof(man)) man;

如果有需要,還可以在最後乙個man

後面加上 ("qqq")之類的引數,呼叫 建構函式 進行初始化。

如**:

#include#include//第一次我忘記加了,但感覺加不加似乎結果都一樣

class player

;player::player()

player::~player() //注意波浪線位置

void player::show()

int player::num = 0;

int main()

cout << "*************這行之前,**塊結束*************" << endl;

delete b; //之所以不能deleteb,是因為b是在**塊內定義的

d->~player();

(*c).~player(); //顯式呼叫物件指標的兩種方式,先用的後呼叫

deletem; //最後再刪除快取區

system("pause");

return 0;

}

顯示:

*************這裡**塊開始*************

*************這行之前,**塊結束*************

請按任意鍵繼續. . .

指標和引用(4)指向指標的指標

1 在程式中可以宣告指向任何資料型別的指標,指標也可以指向指標型別,成為指向指標的指標。下面是乙個使用例子 1 int a 10,b 20 2 int q a 3int p q 4 p 30 2 如果想通過指標在被調函式中修改主調函式的變數,必須將主調函變數 務必確定該變數的型別,有時候可能變數本身...

類和物件程式設計(八) 指向類的指標

乙個指向 c 類的指標與指向結構的指標類似,訪問指向類的指標的成員,需要使用成員訪問運算子 就像訪問指向結構的指標一樣。與所有的指標一樣,您必須在使用指標之前,對指標進行初始化。下面的例項有助於更好地理解指向類的指標的概念 include using namespace std class box ...

13 6指向類成員的指標

1.普通函式指標不能付給類的成員函式 要用類指標呼叫類成員函式 不能滿足三個條件1引數2返回值3他的類 2類成員指標 定義 指向值的型別 類名 指標名 short screen ps screen screen height 3類成員函式的指標 定義 返回值型別 類名 指標名 引數列表 int sc...