可能重複:
Why class size, depends only on data members and not on member functions?C++成員函數和類大小
當我第一次瞭解了繼承,我的老師指出,相對於數據成員,成員函數不改變班級規模。也就是說,如果B類繼承自A類,那麼當且僅當至少添加一個數據成員時,B的大小將大於A的大小,並且不會相對於函數成員數量進行更改。 這是正確的嗎?如果是這樣,這個機制如何工作?似乎兩個成員都應該被關在一起,因此成本會很大。
謝謝 蓋伊
可能重複:
Why class size, depends only on data members and not on member functions?C++成員函數和類大小
當我第一次瞭解了繼承,我的老師指出,相對於數據成員,成員函數不改變班級規模。也就是說,如果B類繼承自A類,那麼當且僅當至少添加一個數據成員時,B的大小將大於A的大小,並且不會相對於函數成員數量進行更改。 這是正確的嗎?如果是這樣,這個機制如何工作?似乎兩個成員都應該被關在一起,因此成本會很大。
謝謝 蓋伊
成員變量存儲爲每一個類實例的一部分。但成員函數不是。
類的每個實例都必須具有每個成員變量的單獨副本。這使每個類都保持獨特。
但是成員函數是代碼。無論您擁有多少個特定類別的實例,都絕對沒有理由擁有多個代碼副本。相同的代碼只是對實例數據進行操作。
由於代碼不同,代碼不是類實例大小的一部分。並且sizeof(myClass)
將不包含代碼佔用的字節。
「方法」在C++ land中不是一個明確定義的術語。正確的術語是「成員函數」,它實際上是在標準中定義的。但+1。 – Griwes
如果類B從類A繼承然後B的大小將大於 A的大小當且僅當將添加至少一個數據成員,以及 不會相對於被改變的功能部件數量。
是的,這是正確的。 (如果B不執行其他方法)。 每個類實例都有一個數據成員的副本和一個指向實際存儲它們的成員函數表的指針。
成員函數的代碼在相同類的不同實例之間共享。如果B不覆蓋基類A的任何成員函數,則A和B都可以共享相同的方法。 當你重寫子類中的成員函數時,基本上你正在改變這個機制,創建一個重載成員函數的新定義,只對定義它的子類可用(es.B)。
正常情況下,成員函數在編譯時綁定。因此,如果您有一個通過指向基類A的指針引用的子類B的實例,並且您調用兩個類中定義的成員函數foo(),則調用的函數將是在基類中實現的函數。 您可以強制成員函數在運行時被綁定,聲明它是虛擬的(被調用的成員函數將是通過基指針指向的類的實際類型之一)。這將導致用於存儲虛擬方法的附加表(虛擬方法表,vtable)以及每個調用的雙指針間接方向。
可以想象,調用成員函數myClass.myMethod(x)
與myMethod(myClass, x)
類似。每個類的每個實例都不需要該函數。您可以使用this
關鍵字訪問此「隱藏的」第一個參數。
「堆」是實現細節;根本沒有堆。將它稱爲動態存儲(用於「堆」)和自動存儲(用於「堆棧」),即使在堆和堆棧不是這些存儲類的實際實現的情況下也是如此。 – Griwes
這並非總是如此。在一個類中有一個或多個虛擬成員函數向其添加虛擬表指針。因此,如果A沒有虛擬成員函數,但B添加了一個虛擬成員函數'sizeof(B)'將大於'sizeof(A)'。 – Csq
@Csq,vptr基本上是成員變量。 – Griwes