C 中使用基類指標操作子類陣列的分析

2021-06-16 00:47:10 字數 1798 閱讀 1161

基礎知識:

ø陣列:在

c/c++

中,陣列是一塊連續的記憶體,記憶體中陣列元素緊密地排列在一起。記憶體的大小

= 元素個數

x 單個元素的大小。

ø操作符

:使用索引訪問資料中的元素。元素在記憶體中的位置為:陣列開始位置

+ 索引

x單個元素的大小。

ø類的例項

:類的例項也占用記憶體。類佔記憶體的大小和類的資料成員有關,類的資料成員越多,那麼占用的記憶體也越大。

ø子類和父類的記憶體分配:父類中的資料成員在前,子類的資料成員在後。

ø指標的加減法:當指標加減乙個整數時,實際的指標位置加減量為:該整數

* 指向型別的大小。如

int *p; p+1

的結果是

p指向位置後的第

4個位元組。

ødelete

:刪除資料。從指標位置開始刪除陣列元素,一直到記憶體塊結束。對於類陣列,會對每個元素呼叫析構函式。

子類陣列

基於以上知識,子類陣列的記憶體分布可以粗略表示為下圖:

使用父類指標時的操作分析

把乙個子類陣列變數賦值給乙個資料元素父類的指標時,指標首先指向陣列頭的位置(如圖)。操作1

:訪問元素

訪問第乙個元素(元素

0)時,沒有任何問題。

訪問下乙個元素時,指標後移。按正常用法使用

++操作或

+=1操作。因為該指標是父類指標,所以偏移量為父類的大小

sizeof(父類)

。這時指標將指向圖中「子類資料」的位置,而不是元素

1的位置。這將導致出錯。使用

操作訪問時也有同樣的問題。操作2

:使用delete

刪除資料:

delete

同樣是按訪問元素的方法逐個析構這些元素。因為它無法找到物件真正的起始位置。

特殊情況

在csdn

的討論中,有人寫出了驗證**,證明這樣訪問沒有問題,如

的**:

#include 

<

iostream.h

>

class

base

virtual 

~base()

};class

child:

public

base

virtual 

~child()

};int

main(

intargc, 

char

*argv)

這段**可以正確執行,但與剛才所說的並不矛盾。這段**中的

child

類屬於特例,因為它沒有資料成員,子類資料是空的。這時如果使用

sizeof

來檢查child

類和base

類的大小,會發現它們是相同的。所以無論使用子類指標還是父類指標,元素定位的計算結果都一樣。

總結:

不要用父類指標去操作子類陣列,雖然你可能碰巧不出錯。

c 基類指標,子類指標,多型

基類指標和子類指標之間的相互賦值 1 將子類指標賦值給基類指標時,不需要進行強制型別轉換,c 編譯器將自動進行型別轉換。因為子類物件也是乙個基類物件。2 將基類指標賦值給子類指標時,需要進行強制型別轉換,c 編譯器將不自動進行型別轉換。因為基類物件不是乙個子類物件。子類物件的自增部分是基類不具有的。...

談談基類與子類的this指標(C )

引入定義乙個類的物件,首先系統已經給這個物件分配了空間,然後會呼叫建構函式 說明 假設存在建構函式 乙個類有多個物件,當程式中呼叫物件的某個函式時,有可能要訪問到這個物件的成員變數。而對於同乙個類的每乙個物件,都是共享同乙份類函式。物件有單獨的變數,但是沒有單獨的函式,所以當呼叫函式時,系統必須讓函...

C 基類與子類 函式指標的定義和轉換

定義乙個類,作為基類 twindow public cwnd 定義乙個字類 class tform public twindow void onbuttonclicked 定義乙個函式指標 typef void twindow functionptr 使用這個指標 functionptr fun f...