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