為什麼 C 中,基類指標可以指向派生類物件?

時間 2021-05-07 23:12:23

1樓:WangKX

語法就這麼規定這叫多型性,如果往深點說,因為子類物件一般比父類物件大,因此這麼指並沒問題,但反過來不行比如子類指標指向父類物件

2樓:馬東啥梅來著

不同型別的指標在記憶體中所佔大小是相同的,區別在於編譯器對於指標的解釋是不同的。

乙個指標指向某個類的物件,實際上是指向該物件所佔記憶體的首位址位置。

那麼當派生類的指標賦給基類指標時,實際上來說它指向類的位址並沒有發生變化,只是編譯器對於該指標的解釋發生變化而已(比如offset)。

3樓:崔幼恬

我來回答乙個簡單的,上面都說的挺對的。。派生類可以繼承基類的成員函式和變數,當然指標也可以繼承。基類指標可以指向派生類也可以指向基類。

但是,反過來卻不行。當然,反過來可以由dynamic_cast方法。

4樓:snowerwkh

這和c++物件的記憶體模型有一定關係的,派生類在記憶體中包括兩個部分:一部分是父類的部分,另一部分才是物件本身擴充套件的。

首先把派生類位址付給基類指標是符合邏輯的,因為派生類包括基類的部分,派生類指標轉換為基類指標後,基類指標指向派生類中基類的部分;另一方面設計為派生類物件位址可以付給基類指標這一特性是實現多型的基礎。

其實在一定的條件下(比如說基類指標本來就指向派生類物件,否則可能會導致指標越界),基類物件指標也可以轉換為派生類物件指標,詳細可以參考下dynamic_cast 、static_cast

5樓:

可以指向,但是無法使用不存在於基類只存在於派生類的元素。(所以我們需要虛函式和純虛函式)

原因是這樣的:

在記憶體中,乙個基類型別的指標是覆蓋N個單位長度的記憶體空間。

當其指向派生類的時候,由於派生類元素在記憶體中堆放是:前N個是基類的元素,N之後的是派生類的元素。

於是基類的指標就可以訪問到基類也有的元素了,但是此時無法訪問到派生類(就是N之後)的元素。

6樓:

來個例子。

struct Base

int m_a;

}struct Derived: public Baseint m_b;

double m_c;

}Base *pBase = NULL;

Derived d;

Derived *pDerived = &d;

d的資料成員有哪些呢? m_a和m_b,m_c;

這三個成員怎麼布局呢? m_a在前,m_b在中間,m_c在最後(不是很嚴謹,你懂我意思就好)。

可以試驗一下:

int *p = reinterpret_cast(&d);

則 m_a == *p; //同為1

即m_a位於d的起始位置,即基類資料成員位於派生類物件的開頭位置(有虛指標則情況略有不同)。

這是pBase和pDerived互轉的基礎。

為什麼要這樣?為了多型。

多型有什麼好處?再舉個例子。

有乙個遊戲,裡面有100種怪物,他們繼承自同乙個怪物基類Mob;

class Mob

現在每種怪物都需要實現乙個攻擊任何怪物的方法。

沒有多型的時候可以這麼寫:

class Mob1 : public Mob有了多型以後:

class Mob1 : public Mob如有疏漏,請傾噴。

7樓:旺旺

題主對型別系統認識不夠,先不要糾結於基類指標能不能指派生類,以及原理如何的問題了……類的繼承就是表示一種「繼承類是基類中的更具體的東西」的關係。比如水果是基類,蘋果是繼承類,顯然蘋果也是一種水果呀,你說「水果能吃」的時候,水果也可以指的是蘋果呀。

型別一致並不是死板地說型別一定要完全一樣,型別是一種約束,幫助你驗證程式的正確性。比如說你女朋友說:「我要吃水果!

」,這時候你送上去乙個「蘋果」,也應該是滿足條件的,而送上去乙個饅頭可能就孤獨一生了,這就是型別系統的作用……

8樓:小蟲飛

計算機的世界是二進位制的,乙個物件就是一塊記憶體,而指標是乙個位址,用於指向乙個記憶體區。

C++中,子類物件可這樣認為,包含乙個父類物件以及自己定義的物件,所以父類指標指向乙個包含自己物件型別的記憶體不就顯得不那麼不可理喻了。這鐘設計才更能體現物件導向中的整合關係,才能更好地發揮物件導向的優勢。

當然。如果在C的世界裡面,你乙個指標可以指向任何一塊記憶體的,指向任何乙個物件,關鍵合不合法在於你如何讓去使用該指標。

是否可以在成員類中定義 指向父類的指標 ?

張翼德 這要分class B的宣告 h 和實現 cpp 檔案兩個地方 如果你在class B的宣告 h 裡沒有用到任何class A 的成員,比如就像你問題裡寫的那樣,只是用到了class A的名字,那你只要在class B前面宣告 class A 讓compiler知道 A是個class 就行了,...

C 中為什麼派生類中只有基本型別時,delete乙個指向派生類的基類指標時卻沒有記憶體洩漏?

你試試這樣 class widget public QWidget MSVC的string實現方式是SSO,大致的原理是內建乙個char棧陣列,如果字串很短的話就不使用堆記憶體,你那個寫法string還是空的,沒有分配堆記憶體,從頭到尾都只在棧上有資料當然不存在記憶體洩漏問題,所以你還需要強制地給s...

為什麼派生類的建構函式需要對基類進行初始化,而不能只對派生類中的子物件進行初始化?

原子筆 背景 乙個c 沒有虛繼承的物件,如果把基類看成樹葉子,最終派生類部分看成樹根,那麼構造的過程是個先葉子後根的 反 深度優先遍歷的過程。有菱形繼承,那麼樹變成圖,繼續深度優先遍歷 注意有的節點會以不同的位址被遍歷2次,沒事 有虛繼承時要稍微複雜些,有的線要一分為二,有的線的方向要反過來。廢話不...