原文連結:http://blog.csdn.net/zhangxaochen/article/details/8032758
這裡“空類”是在說什麼都沒有或者只包含了非虛函數的類。
以前只是有印象知道列印 sizeof(空類)會輸出“1”,但是也不知為什麼。今天偶然看到,說是:
“一個空類也要執行個體化,所謂類的執行個體化就是在記憶體中分配一塊地址,每個執行個體在記憶體中都有獨一無二的地址。同樣空類也會被執行個體化,所以編譯器會給空類隱含的添加一個位元組,這樣空類執行個體化之後就有了獨一無二的地址了。所以空類的sizeof為1”
其餘什麼類的4位元組對齊,虛表佔用空間,子類繼承了父類佔用的空間,類內static不佔類空間 就不再提。
另外,借了段代碼,略作示範:
class Base{public:Base(){};virtual ~Base(){};void set_num(int num){a=num;}virtual int get_num(){return a;}private: int a; char *p;};class Derive:public Base{public:Derive():Base(){};~Derive(){}; virtual int get_num(){return d;}private:static int st; int d; char *p;char c;};int main(){ cout<<sizeof(Base)<<endl;cout<<sizeof(Derive)<<endl;return 0;}
輸出:
12
24
==========================================================
2. placement new
以前學C++文法的時候沒有接觸過,最近看 box2d的源碼的時候見識了這樣的文法。
說白了就是 operator new 的一個重載、全域版本,與平常的new操作符的不同在於,placement new 指定一塊記憶體位置,然後在這塊記憶體上調用類的建構函式,劃分記憶體。
所以placement new 接受兩個參數,一個是指定的記憶體位址,另一個是類名,原型如下:
void *operator new( size_t, void *p ) throw() { return p; }
用法如下:
void* mem=malloc(sizeof(B));B* bb=new (mem) B;
乍一看 new B 中間插了一個括弧,的確很彆扭不過這樣的用法的好處是避免了“動態分配記憶體時尋找可用記憶體” 這個動作消耗的時間,所以說他
“placement new非常適合那些對時間要求比較高,長時間運行不希望被打斷的應用程式”
box2d 中跟 placement new 相關的源碼是這樣的:
b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def){ ...... b2BlockAllocator* allocator = &m_world->m_blockAllocator; void* memory = allocator->Allocate(sizeof(b2Fixture)); b2Fixture* fixture = new (memory) b2Fixture; .....}
可以看到 Allocate(sizeof(b2Fixture)) 函數就相當於 malloc,只不過 box2d 自己做了記憶體管理的工作。因為 物理引擎總是需要大量的浮點運算,因此也符合“時間要求較高,長時間運行不希望被打斷”這一斷言。
原文連結:http://blog.csdn.net/zhangxaochen/article/details/8032758
{{OVER}}