A C class, CSquare, uses multiple inheritance from CBase and an M class interface, MPolygon. The object is instantiated and the M class interface pushed on to the cleanup stack. The object is later destroyed by a call to PopAndDestroy(). If the pushing was done with CleanupStack::PushL(), the PushL(TAny*) would be used because the pointer is not a CBase pointerThe PushL(TAny*) overload means that User::Free() is invoked on the pointer on cleanup, but this would result in a User 42 panic. That’s because User::Free() can't find the heap information it needs to release the memory to the system when passed an M class pointer to the sub-object of a C class. Even if it could, the virtual destructor of CSquare would not be called, so the best-case scenario would be a memory leak! The solution is to use CleanupDeleteL() to call delete on the M class pointer and invoke the virtual destructor correctly for the CSquare class.
对于同时继承了cbase和m接口的类,如果使用pushL(),将会重载 PushL(TAny*) ,这就意味着异常退出会调用User::Free() 来清除,但free()不能找到内存中需要释放的信息,析构函数不能被调用,从而引发User 42 panic.解决方案就是使用CleanupDeleteL() t来调用m类指针的删除操作以及cbase析构函数。
class MPolygon
{
public:
virtual TInt CalculateNumberOfVerticesL() =0;
virtual ~MPolygon(){};
};
class CSquare : public CBase, public MPolygon
{
public:
static CSquare* NewL();
virtual TInt CalculateNumberOfVerticesL();
virtual ~CSquare(){};
private:
CSquare(){};
};
enum TPolygonType { ESquare };
static MPolygon* InstantiatePolygonL(TPolygonType aPolygon);
MPolygon* InstantiatePolygonL(TPolygonType aPolygon)
{
if (ESquare==aPolygon)
return (CSquare::NewL());
else
return (NULL);
}
/*static*/ CSquare* CSquare::NewL()
{ // No two-phase construct needed here.
CSquare* me = new(ELeave) CSquare();
return (me);
}
TInt CSquare::CalculateNumberOfVerticesL()
{ // Simple implementation, but others may leave.
return (4);
}
void DoStuffL()
{
MPolygon* square = InstantiatePolygonL(ESquare);
CleanupDeletePushL(square);
// ... Leaving calls go here.
ASSERT(4==square->CalculateNumberOfVerticesL());
CleanupStack::PopAndDestroy(square);
}