類A(比方說)中,具有僅具有成員函數存儲器靜態函數VS成員函數
如果我創建類A的1000個實例作爲類只包含靜態所有靜態成員函數僅 B類(比方說)成員函數,即使有1個實例或1000個實例,內存也不會增加。
但是,對於B類。如果我創建了1000個實例,是否會增加內存(即使是最輕微的,可能是指向成員函數集的每個對象的指針)?
如果否,那麼編譯器如何保存特定對象的成員函數信息的跟蹤?
類A(比方說)中,具有僅具有成員函數存儲器靜態函數VS成員函數
如果我創建類A的1000個實例作爲類只包含靜態所有靜態成員函數僅 B類(比方說)成員函數,即使有1個實例或1000個實例,內存也不會增加。
但是,對於B類。如果我創建了1000個實例,是否會增加內存(即使是最輕微的,可能是指向成員函數集的每個對象的指針)?
如果否,那麼編譯器如何保存特定對象的成員函數信息的跟蹤?
對於初學者,您可能會嘗試輸出sizeof(A)
和sizeof(B)
。但 幾件事情要記住:
無論數量或類型的成員中,C++禁止一類 的大小爲0,所以靜態成員與否,A
每個實例都將 採取一些記憶;和
的非虛擬函數的解析做完全由編譯 時間,所以沒有必要編譯任何東西添加到 類的。 (虛擬函數通常會將一個指針的大小增加到該類,而不管您的類有多少個虛擬函數。)
是否會增加內存(即使是最輕微的,可能是指向成員函數集的每個對象的指針)?
NO。
非虛擬成員函數不會影響類的對象大小。
但是,虛擬成員函數的存在通常會增加類對象的大小。
注意,後者是純粹的實現具體的細節,但由於所有已知的編譯器實現了使用v-table
和v-ptr
虛擬機制,這是合理的假設,幾乎所有的編譯器會顯示添加v-ptr
到的每一個對象的相同行爲多態類,從而按類似於v-ptr
的大小增加類對象的大小。
如果我們是只是談論成員函數,印記將是相同的。一個成員函數不會佔用更多的內存,它所包含的類實例化的次數越多(因爲this
指針被傳遞給它)。只有類的數據成員纔會在每個類實例化時佔用更多的內存,因爲它們對於類的每個實例都是唯一的。
所以要回答你的第二個問題,它在調用類的非靜態成員函數時通過this
指針的用戶保持「跟蹤」。
虛擬方法讓事情變得更復雜一些,但是你的問題並沒有涉及到這個特定的習慣用法。
在較低的級別,沒有對象,只是函數調用。隱含的this
參數被傳遞給成員函數。當我們調用void B::f(){ mem1(); }
時,編譯器將其視爲B::mem1(this)
。因此,即使您擁有數百萬個B類對象,也會有一個函數mem1
期待B類對象。
虛擬函數是不同的。他們從表中查找,但是,查找結果取決於[實際]類型this
(在mem1(this)
中),而不是由this
指向的對象。
您可以使用sizeof
函數來測試函數是否佔用類對象的內存。
class A{};
class B{
void foo(){};
};
class C{
static void foo();
};
class D{
virtual void foo();
};
class E{
virtual void foo1();
virtual void foo2();
}
sizeof(A)=1
sizeof(B)=1
sizeof(C)=1
sizeof(D)=4
sizeof(E)=4
一流A
B
C
對象的內存是零。但是如果他們的記憶爲零,編譯將無法區分這些類。所以編譯加上char
來區分這些類。所以:
sizeof(A)=1
sizeof(B)=1
sizeof(C)=1
所以,你可以看到成員函數和靜態成員函數不佔用memory.So他們不會增加內存。
但是如果class具有虛函數,它會添加4個字節,並且它只添加4個字節是否具有多少虛函數。因爲它只添加一個指向虛表的虛表,其中包含虛函數的點。
靜態成員函數和普通成員函數的區別很簡單。當調用正常成員函數ECX寄存器被設置爲類實例的 你可以看到一個附加
LEA ECX,INSTANCE_NAME [EBP]
如果deassemble
的部件的地址函數使用此寄存器訪問類 ,所以內存使用不會增加,但計算時間會增加
也許只有虛擬方法;) – 2012-03-13 11:32:04
@VJovic:的確如此! – 2012-03-13 11:33:57