Symbian 清除栈 CleanupStack
2010-06-03 23:05:00 来源:WEB开发网因此,对象应该只被清除栈或另一个对象所引用,而不能同时被两者引用。类似的,永远不要将类成员变量压入清除栈。
小例子:
void TransferOwnershipExampleL()
{
CClanger* clanger = new( ELeave ) CClanger();
CleanupStack::PushL(clanger);//压入清除栈
iMemberObject->TakeOwnershipL(clanger);//类成员iMemberObject获得了对象所有权
CleanupStack::Pop(clanger);//这里就必须从清除栈中弹出对象指针
//调用完异常代码后将对象指针从清除栈中弹出
}
comments:永远不要将类成员变量压入清除栈,会导致double-deletion
命名问题:
如果有对象被压入清除栈,并直至函数返回时还保留在清除栈上,则该函数应该以”C”作为后缀。这就告诉函数调用者,如果函数正常返回,清除栈上仍然有多余的对象。
CSiamese* CSiamese::NewLC(TpointColor aPointColor)
{
CSiamese* me = new( ELeave ) CSiamese( aPointColor );
CleanupStack::PushL( me );
me->ConstructL();
return me;
}
上面的函数实际是用在对象的二阶段构造中,其中,压入清除栈后并没有弹出,因此命名时必须要用”C”结尾。
三、对非CBase派生类使用清除栈
看一下CleanupStack::PushL()的三种重载形式:
(1)CleanupStack::PushL(CBase* aPtr)
(2)CleanupStack::PushL(TAny*)
(3)CleanupStack::PushL(TCleanupItem)
第一种形式:用在CBase的派生类对象上,当popanddestroy时,会调用该派生类对象的析构函数,跟C++一样,先调用派生层次最深类的析构函数,然后沿着派生层次顺次向上调用析构函数,最后调用CBase的空析构函数。
第二种形式:如果在定义一个C类时,忘记了从CBase派生,那么就会很危险(千万不要这么做,如果你这么做了,出什么事情,你自己要负全责),因为在调用PushL时,实际上调用的是CleanupStack::PushL(TAny*)这个方法,这样在pop时就不会调用这个类的析构函数,仅仅是清除它所指向的堆内存而已。实际上该方法被用来将没有析构函数的、基于堆的对象的指针压入清除栈(比如T类对象或结构体)。
第三种形式:接收一个TcleanupItem类型对象作为参数,这个函数可以使我们将其他类型的对象或那些具有定制的清除例程的对象压入清除栈。TCleanupItem对象封装了一个指向要保存在清除栈上对象的指针和一个指向提供相应对象清除操作的函数指针。
Tags:Symbian 清除 CleanupStack
编辑录入:coldstar [复制链接] [打 印]更多精彩
赞助商链接