清除栈 CleanupStack
清除栈 CleanupStack
清除栈用于发生异常情况下对压入栈的对像指针及指针指向的堆空间进行释放,如果执行正确,则需要弹出栈
要遵守以下规则:
- 如果存在发生异常信息的危险,且其它地方不存在对已分配堆的对像的引用,则指向该对像、具有本地作用域的指针必须被推入清除栈
- 绝对不要将实例数据,类实例拥有的数据推入清除栈中
- 构造函数与析构函数不能异常退出,并且构造函数不能完成构造,要通过二次构先造(原话是:析构函数不能完成构造,感觉有错误)
- 删除成员指针后,在重新分配前将其初始化为 0
#ifndef MTest1 #define MTest1 #include <e32base.h> #include "MClass1.h" // 这个不用管, MClass1 是项目名 #include <e32cons.h> // 基类的定义,只有一个虚方法 class CProtocol:public CBase { public: virtual void HandleEvent(TInt aEventCode) =0; }; // 用户类,用来操作 protocol 类 class CProtocolUser:public CBase { public: static CProtocolUser* NewLC() { CProtocolUser* self = new(ELeave) CProtocolUser(); CleanupStack::PushL(self); self->ConstructL(); return self; } static CProtocolUser* NewL() { CProtocolUser* self = CProtocolUser::NewLC(); CleanupStack::Pop(); return self; } // 传入一个 CProtocol 的指针,去调用 CProtocol 的 虚方法 void DoSomething(CProtocol* aProtocol,TInt aInt=0) { _LIT(KBeignMsg,"DoSomething begin\n"); console->Printf(KBeignMsg); // 这里调用 aProtocol->HandleEvent(aInt); _LIT(KEndMsg,"\nDoSomething end\n"); console->Printf(KEndMsg); } protected: void ConstructL() { } }; // 从CProtocol 派生出一个类 class CProtocolProvider :public CProtocol { public: ~CProtocolProvider() { delete iProtocolUser; //delete iProtocolUser2; } void HandleEvent(TInt aEventCode) { _LIT(KEventCode,"this EventCode is %d"); console->Printf(KEventCode,aEventCode); } static CProtocolProvider* NewLC() { CProtocolProvider* self = new (ELeave) CProtocolProvider(); CleanupStack::PushL(self); self->ConstructL(); return self; } static CProtocolProvider* NewL() { CProtocolProvider* self = CProtocolProvider::NewLC(); CleanupStack::Pop(); return self; } // 通过这句调用 void CallProtocolUser() { iProtocolUser->DoSomething(this); } protected: void ConstructL() { iProtocolUser = CProtocolUser::NewL(); // 这样创建,则不需要去释放,也就是析构函数中不 delete // 会报错 /* 下面我用 NewLC 创建,在析构时不去 delete 这个 iProtocolUser2 ,程序运行会自动退出,应该是有错误 而我用 NewL,在析构时去 delete iProtocolUser2 ,程序不会自动退出,说明是正确的,问题是为什么 NewLC会出错呢 */ //iProtocolUser2 = CProtocolUser::NewL(); iProtocolUser2 = CProtocolUser::NewLC(); } private: // 把这个声明成 public ,则调用时,可以通过另一种方式 // 下面的 public 是另一个方式调用的例子 CProtocolUser* iProtocolUser; public: CProtocolUser* iProtocolUser2; }; #endif |
上面这段代码就是对 Cleanup 不理解造成的,另个,对于类成员,不能压栈,需要在析构函数处去 delete
安平2009@原创
qi_jianzhou@126.com