舉個(gè)簡(jiǎn)單的例子: class Point { private: int x; int y; public: void Set(int a,int b) { x=a; y=b; } void Print() { cout<<"("<<x<<","<<y<<")"<<endl; } }; void main() { Point p1; Point *p2=new Point(); p1.Set(1,2); p2->Set(4,5); p1.Print(); p2->Print(); delete p2; } 對象p1,p2的定義方式有何本質(zhì)不同?用哪種方式比較好?最佳答案 p1有系統創(chuàng )建并釋放,你不要擔心會(huì )出現內存泄露,但是生命期只有在本區域的大括號內,出了大括號就沒(méi)用了。P2是指針,要自己釋放,用不好很危險,用好了功能強大,因為他可以賦值給全局的變量,一下子從局部變量變成全局變量,還能把對象作為函數返回值。
-----------------------------------------------
一個(gè)類(lèi)的實(shí)例化對象所占空間的大???
注意不要說(shuō)類(lèi)的大小,是類(lèi)的對象的大小.
首先,類(lèi)的大小是什么?確切的說(shuō),類(lèi)只是一個(gè)類(lèi)型定義,它是沒(méi)有大小可言的。
用sizeof運算符對一個(gè)類(lèi)型名操作,得到的是具有該類(lèi)型實(shí)體的大小。
如果
Class A;
A obj;
那么sizeof(A)==sizeof(obj)
那么sizeof(A)的大小和成員的大小總和是什么關(guān)系呢,很簡(jiǎn)單,一個(gè)對象的大小大于等于所有非靜態(tài)成員大小的總和。
為什么是大于等于而不是正好相等呢?超出的部分主要有以下兩方面:
1) C++對象模型本身
對于具有虛函數的類(lèi)型來(lái)說(shuō),需要有一個(gè)方法為它的實(shí)體提供類(lèi)型信息(RTTI)和虛函數入口,常見(jiàn)的方法是建立一個(gè)虛函數入口表,這個(gè)表可為相同類(lèi)型的對象共享,因此對象中需要有一個(gè)指向虛函數表的指針,此外,為了支持RTTI,許多編譯器都把該類(lèi)型信息放在虛函數表中。但是,是否必須采用這種實(shí)現方法,C++標準沒(méi)有規定,但是這幾戶(hù)是主流編譯器均采用的一種方案。
2) 編譯器優(yōu)化
因為對于大多數CPU來(lái)說(shuō),CPU字長(cháng)的整數倍操作起來(lái)更快,因此對于這些成員加起來(lái)如果不夠這個(gè)整數倍,有可能編譯器會(huì )插入多余的內容湊足這個(gè)整數倍,此外,有時(shí)候相鄰的成員之間也有可能因為這個(gè)目的被插入空白,這個(gè)叫做“補齊”(padding)。所以,C++標準緊緊規定成員的排列按照類(lèi)定義的順序,但是不要求在存儲器中是緊密排列的。
基于上述兩點(diǎn),可以說(shuō)用sizeof對類(lèi)名操作,得到的結果是該類(lèi)的對象在存儲器中所占據的字節大小,由于靜態(tài)成員變量不在對象中存儲,因此這個(gè)結果等于各非靜態(tài)數據成員(不包括成員函數)的總和加上編譯器額外增加的字節。后者依賴(lài)于不同的編譯器實(shí)現,C++標準對此不做任何保證。
C++標準規定類(lèi)的大小不為0,空類(lèi)的大小為1,當類(lèi)不包含虛函數和非靜態(tài)數據成員時(shí),其對象大小也為1。
如果在類(lèi)中聲明了虛函數(不管是1個(gè)還是多個(gè)),那么在實(shí)例化對象時(shí),編譯器會(huì )自動(dòng)在對象里安插一個(gè)指針指向虛函數表VTable,在32位機器上,一個(gè)對象會(huì )增加4個(gè)字節來(lái)存儲此指針,它是實(shí)現面向對象中多態(tài)的關(guān)鍵。而虛函數本身和其他成員函數一樣,是不占用對象的空間的。
我們來(lái)看下面一個(gè)例子:(此例子在Visual C++編譯器中編譯運行)
#include <iostream>
using namespace std;
class
{
};
class
{
char
void
{
}
};
class
{
char
char
virtual
{
}
};
class
{
int
virtual
{
}
};
void
{
A
B
C
D
cout<<sizeof(a)<<endl;//result=1
cout<<sizeof(b)<<endl;//result=1
cout<<sizeof(c)<<endl;//result=8
//對象c實(shí)際上只有6字節有用數據,但是按照上面第二點(diǎn)編譯器優(yōu)化,編譯器將此擴展為兩個(gè)字,即8字節
cout<<sizeof(d)<<endl;//result=8
}
綜上所述:
一個(gè)類(lèi)中,虛函數、成員函數(包括靜態(tài)與非靜態(tài))和靜態(tài)數據成員都是不占用類(lèi)對象的存儲空間的。
對象大小=
聯(lián)系客服