Symbian^3對標準C++的支持
聲明:原文來至 Standard C++ Support on the Symbian Platform,水平有限,敬請諒解。
http://library.forum.nokia.com/index.jsp?topic=/Nokia_Symbian3_Developers_Library/GUID-2CCD1748-9EDE-5383-9941-A3051E06F3E2.html
(注:S60平臺增強了對標準c++的支持,開發者可以把代碼編譯成標準C++類型的庫,STDEXE、STDDLL、STDLIB)
本節講述Symbian^3對標準C++運行時特性的支持
提綱:
全局操作符new (global operator new)
new_handler
全局對象的析構 (global objects destruction)
STL
全局操作符new (global operator new)
在標準C++中,new分配內存失敗時,如果設置的處理錯誤的handler,則調用這個handler,如果沒有設置handler,則拋出exception (std::bad_alloc)。但是在symbian C++中,動態分配內存失敗返回NULL指針。
所以當你編寫C++代碼時,必須清楚當前使用標準C++還是Symbian C++。
你可以使用下列辦法,在Symbian平臺上使用標準C++。
1> 編譯成STD類型的應用程序或庫
2> 在MMP文件中使用STDCPP關鍵字
注意,使用全局操作符new帶來的問題參見"new操作符的使用"。
警告,symbian平臺不允許你混合使用全局操作符new和symbian C++操作符new。
下面的例子演示瞭如何在MMP文件中使用STDCPP關鍵字來使用標準C++的操作符new,而不用把工程編譯成STD類型。
//operator_new_example.mmp
Target operator_new_example.exe
Targettype exe
//The STDCPP keyword specifies Standard C++
STDCPP
Source operator_new.cpp
Systeminclude /epoc32/include/stdapis/stlportv5
Systeminclude /epoc32/include/stdapis
Library libstdcppv5.lib libc.lib
Capability all -tcb
//operator_new.cpp
#include <new>
int main()
{
try
{
int *ptr = new int(0);
//do something
}
catch(std::bad_alloc)
{
return 1;
}
delete ptr;
return 0;
}
new_handler
標準C++使用new分配內存失敗時,如果設置了new_handler,則會使用這個new_handler處理這個錯誤。現在Symbian C++也支持這個特性。
下面的例子演示瞭如何在Symbian平臺上使用這個特性。(別忘了MMP中使用STDCPP關鍵字或者使用STDEXE/STDDLL編譯類型)
#include <new>
int one_huge_chunk = 0xa000;
int *last_huge_chunk=NULL;
void foo()
{
/*
* new_handler釋放最後一次成功分配的內存,來保證下一次分配成功。
*/
delete [] last_huge_chunk;
}
void bar()
{
last_huge_chunk = new int[one_huge_chunk];
}
int main()
{
std::new_handler h_new;
try
{
while(1)
{
// 不停地分配內存,直到系統內存耗盡,不能再分配出內存。
bar();
}
}
catch(std::bad_alloc ba)
{
/*
* 沒有設置new_hanlder時,分配失敗會得到一個std::bad_alloc類型的exception,
* 下面設置new_handler。
*/
h_new = (std::new_handler)&foo;
try
{
/*
* 測試new_handler釋放一次內存後,還能否再分配出內存。
*/
bar();
}
catch(...)
{
}
return 0;
}
/*沒有收到std::bad_alloc錯誤*/
return 1;
}
全局對象的析構 (global objects destruction)
動態或靜態加載的DLL現在都支持全局對象了,它們的析構函數也會被調用,當該DLL的引用數(reference count)爲0時。
舉例:
// glob_data.cpp
#include <iostream>
// class definition
class AClass
{
AClass()
{
std::cout << “ctor()” << std::endl; // inline constructor
}
~AClass()
{
std::cout << “dtor()” <<std::endl; // inline destructor
}
};
AClass GlobData; // 全局對象
int main()
{
std::cout << “main()” << std::endl;
}
輸出結果
ctor
main
dtor
(題外話,偶就是碰到這個狗血問題才閱讀這篇文檔。S60的3rd和5th版本不支持全局對象的析構,特別是這裏可能引發內存泄漏(PANIC ALLOC),所幸Symbian^3非常不完美地增加了這一支持。)
(雖然例子代碼能釋放全局對象,但偶在某處全局對象卻始終無法調用析構函數,不過這個問題在其它代碼不能重現,原因還沒找到,同樣的代碼Android NDK和WM卻都能,所以說它非常不完美。全局對象最好還是要手動釋放。)
STL
增加了標準模板庫的一些新特性。
基於STLPort v5.1.4
頭文件位於${EPOCROOT}/epoc32/include/stdapis/stlportv5
必須使用庫libstdcppv5.lib