Symbian下,new、NewL和NewLC的区别(转)

 对于C++,new一个对象是这样写的:
        char* pChar = new(ELeave) char[];
        CObject* pObject = new(Leave) CObject();
       对char的内存开辟,是没有什么问题的,对CObject,是有问题的,假设CObject中有两个成员变量,a和b,都是需要内存分配的,在CObject的构造函数中,先给a分配了内存,再给b分配内存时,出现异常,这时,由于CObject还没有构建完毕,异常出现时CObject的析构函数不会被调用,故a的内存被泄露。
       怎么办?Symbian的设计者设计出了这样一套方案:所以的类,都需要继承自CBase,并重载NewL和NewLC、ConstructL方法,所有构造函数中可能产生异常的操作,均要放到ConstructL中进行。用户使用该类时,需要通过NewL或者NewLC方法进行构造,不再使用new。NewL和NewLC的代码如下:
        static CFoo *NewL()
       {
               CFoo *self = new(ELeave) CFoo();
               CleanupStack::PushL(self);
               self->ConstructL();
               CleanupStack::Pop();
               return self;
         }
        static CFoo *NewLC()
       {
               CFoo *self = new(ELeave) CFoo();
               CleanupStack::PushL(self);
               self->ConstructL();
               return self;
         }
       这样做的好处时,类的构造函数不再进行任何产生异常的操作,故不会产生异常,只要类的内存分配成功,则对象建立就成功了,这样即使在ConstructL中产生异常操作,程序也会调用类的析构函数,将内存删除。
       可以看到,如果在new出了对象之后,如果还要进行一些可能产生异常的操作,则使用NewLC较好,如果不进行可能产生异常的操作,则使用NewL较好。
       同理可以推论出,对于类里面的成员变量,使用NewL比较好,因为即使操作异常,类的析构函数会将成员删除,故不需要清除栈,但对于函数里面的临时变量,则使用NewLC比较好(最后使用CleanStack::PopAndDestroy () 进行删除)。

      COM里面采用的返回值的Construc,是一样的道理,与qz讨论一下优劣问题,不好说。

posted @ 2010-05-25 13:58  清飞  阅读(399)  评论(0)    收藏  举报