当使用new构造对象时,发生内存分配。虽然返回值NULL表明内存分配失败,若希望产生一个异常退出,只要在new和类名称间插入一个(ELeave)。
CMyObject *obj = new (ELeave) CMyObject;
它是new运算符的重载,对于一条传统的new语句(CMyObject *obj = new CMyObject)来说,编译器以这样的方式调用内置的new函数原型:new(TInt)――TInt参数是对象的大小。但是如果在new后加ELeave,编译器则改为这样的调用函数原型:new(TInt,TLeave),TInt是对象的大小,而TLeave是参数ELeave的数据类型,ELeave只是一个哑元变量,它的目的是引起该重载new的调用,Symbian OS实现了这个重载new函数是用于在内存分配失败时异常退出。
当使用Eleave构造对象时,清理时要小心,因为有可能在构造期间发生异常退出。
现在有一种情形:如果在构造函数本身发生异常退出呢?这是Symbian OS中的一个问题,在new运算符函数分配内存后,就立即(在后台)调用构造函数,没有机会让程序员把指向已分配内存的指针压入清理栈。因此,如果在构造期间发生异常退出,就会得到一个该类已分配内存的孤立指针。
Symbian对应这个问题的策略是“双阶构造函数”,类中提供一个名为ContructL()的方法用来完成对象的构造(成员的堆分配)。
CMyObj* CMyObj::NewL()
{
CMyObj *self = NewLC();
CleanupStack::Pop();//调用LC函数后,要负责弹出操作
return self;
}
CMyObj* CMyObj::NewLC()
{
CMyObj *self = new(ELeave)CMyObj;
CleanupStack::PushL(self);//LC函数要负责将指针压入清理栈
self->ConstructL();//构造内部成员
return self;
}
C++里面的 new 操作符实际上完成2件事,第一根据对象类的大小在堆上分配一块内存并获得指向内存的指针,第二利用指针调用类的构造函数,最后把指针返回。
① 函数的形参又称“哑元”,实参又称“实元”。
② Cleanupstack:清理栈
③ 好文推荐:http://blog.joycode.com/yaodong/articles/94824.aspx