Cocos2d-x開發中C++內存管理
由於開始並沒有介紹C++語言,C++的內存管理當然也沒進行任何的說明,為了掌握Cocos2d-x中的內存管理機制,是有必要先了解一些C++內存管理的知識。
C++內存管理非常復雜,如果完全地系統地介紹可能需要一本書的篇幅才能解釋清楚。這裡只給大家介紹C++內存管理最為基本的用法。
內存分配區域
創建對象需要兩個步驟:第一步,為對象分配內存,第二步,調用構造函數初始化內存。在第一步中對象分配內存時候,我們可以選擇幾個不同的分配區域,這幾個區域如下:
棧區域分配。棧內存分配運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。由處理器自動分配和釋放,用來存放函數的參數值和局部變量的值等。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。
堆區域分配。從堆上分配,亦稱動態內存分配。由開發人員分配釋放,如果不釋放,程序結束時由操作系統回收。 程序在運行的時候用malloc或new申請任意多少的內存,開發人員自己負責在何時用free或delete釋放內存。動態內存的生存期由開發人員決定,使用非常靈活,但問題也最多。
在靜態存儲區域分配。這個內存空間在程序的整個運行期間都存在,內存在程序編譯的時候就已經分配好。它可以分配全局變量和靜態變量。
動態內存分配
動態內存分配最為靈活但是問題也很多,我們重點介紹動態內存分配。動態內存使用malloc或new分配內存,使用free或delete釋放內存。其中malloc和free是成對的,new和delete是成對的。
1、malloc和free使用
malloc和free是C/C++語言的標准庫函數,主要是在C中使用。使用malloc創建對象,不會自動調用構造函數初始化內存。使用free釋放對象,不會自動調用析構函數清除內存。
使用malloc和free分配和釋放內存的實例代碼如下:
#include
using namespace std;
class MyObject
{
public :
MyObject(){ ①
cout << "call constructor." << endl;
}
~MyObject(){ ②
cout << "call destructor." << endl;
}
void initialize(){ ③
cout << "call initialization." << endl;
}
void destroy(){ ④
cout << "call destroy." << endl;
}
};
int main(){
MyObject *obj = (MyObject *)malloc(sizeof(MyObject)); // 申請動態內存 ⑤
obj->initialize(); ⑥
//TODO
obj->destroy(); ⑦
free(obj); ⑧
obj = NULL;
return 0;
}
上述代碼創建了聲明了MyObject類,其中第①行代碼是聲明構造函數,第②行代碼是聲明析構函數。第③行代碼是聲明初始化函數void initialize()在使用malloc分配內存時候不能調用構造函數,通過調用該函數初始化該對象。第④行代碼是聲明清除函數void destroy()在使用free釋放對象內存時候,通過調用該函數清除該對象的一些資源。
第⑤~⑧行是調用MyObject類進行測試,其中第⑤行代碼MyObject *obj = (MyObject *)malloc(sizeof(MyObject))是使用malloc函數分配內存,使用該函數需要指定對象的長度,還有malloc函數返回值是void*,由於C++不允許void*賦值給其它指針,所以需要強制類型轉換。由於構造函數不能顯式調用,所以需要第⑥行代碼是初始化對象。
第⑧行代碼free(obj)是釋放obj對象內存。在釋放對象內存之前,我們在第⑦行代碼obj->destroy()是在釋放對象內存之前調用,清除該對象的一些資源,它的作用相當於析構函數。但是真正的析構函數~MyObject()並沒有調用。
運行結果如下:
call initialization.
call destroy.
2、new和delete使用
與malloc和free不同,new和delete不是函數庫,而是C++的運算符。new運算符能夠完成創建對象所有步驟(即:第一步,為對象分配內存,第二步,調用構造函數初始化內存),它也會調用構造函數。實例代碼:
MyObject *obj = new MyObject();
構造函數可以重載,根據用戶傳遞的參數列表,決定調用哪個構造函數進行初始化對象。
new運算符反操作運算符是delete,delete先調用析構函數,再釋放內存。實例代碼:
delete obj;
obj是對象指針,obj只能釋放new創建的對象,不能釋放有malloc創建的。而且采用delete釋放後的對象指針,需要obj=NULL以防止“野指針”。
提示 一種情況是,指針變量沒有被初始化,它的指向是隨機的,它會亂指一氣,並不是為NULL。如果使用if語句判斷,則認為是有效指針。另外情況是,指針變量被free或者delete之後,它們只是把指針所指的內存給釋放掉,但並沒有把指針本身清除,此時指針指向的就是“垃圾”內存。如果使用if語句判斷,也會認為是有效指針。“野指針”是很危險的,良好的編程習慣是,這兩種情況下都需要將指針設置為NULL,這是避免“野指針”的唯一方法。
使用new和delete分配和釋放內存的實例代碼如下:
#include
using namespace std;
class MyObject
{
public :
MyObject(){
cout << "call constructor." << endl;
}
~MyObject(){
cout << "call destructor." << endl;
}
void initialize(){
cout << "call initialization." << endl;
}
void destroy(){
cout << "call destroy." << endl;
}
};
int main(){
MyObject *obj = new MyObject(); // 申請動態內存
//TODO
delete obj;
obj = NULL;
return 0;
}
同樣是MyObject類,采用是new分配內存,delete釋放內存。程序運行會調用構造函數和析構函數。運行結果如下:
call constructor.
call destructor.
更多內容請關注國內第一本Cocos2d-x 3.2版本圖書《Cocos2d-x實戰:C++卷》本書交流討論網站:http://www.c
ocoagame.net更多精彩視頻課程請關注智捷課堂Cocos課程:http://v.51w
ork6.com歡迎加入Cocos2d-x技術討論群:257760386歡迎關注智捷iOS課堂微信公共平台