Cleanup stack giúp chúng ta giải quyết vấn đề giải phóng vùng nhớ khi leave xảy ra, nhưng có một tình huống mà cleanup stack không giải quyết được, đó là khi biến thành viên của lớp này là một đối tượng của lớp khác và biến này được khởi tạo trong contructor của lớp. Khi đó, có thể xảy ra trường hợp như sau : Các hàm cấp phát tài nguyên cho các biến thành viên vẫn được thực hiện, trong khi đó, việc cấp phát tài nguyên cho đối tượng cha không thể thực hiện được, lúc đó sẽ xảy ra lỗi mà chúng ta không thể kiểm soát được : vùng nhớ của các biên thành viên sẽ không được giải phóng và xảy ra tình trạng “lủng” bộ nhớ.
Để giải quyết tình trạng đó, Symbian đưa ra một luật, đó là : contructor không được phép leave. Để thực hiện việc cấp phát tài nguyên cho các biến thành viên và cho đối tượng cha được thực hiện thông qua việc khởi tạo 2 pha (Two phase constructor) như sau :
• Pha 1: Phần constructor đơn giản, không leave. Phần này sẽ được gọi liền ngay sau khi toán tử new được gọi.
• Pha 2: Một hàm khác sẽđảm nhận việc hoàn tất khởi tạo các biến thành viên, trên Symbian thường đặt tên là ConstructL(), hàm này có thể leave.
Tìm hiểu công nghệ Bluetooth và viết ứng dụng minh họa Ví dụ về khởi tạo hai pha:
Class CClassB:public CBase { public: ~CClassB(); CClassB(); void ConstructL(); CClassX *iX; };
CClassB::CClassB() // Khởi tạo pha 1, không leave { } CClassB::~CClassB() { detele iX; }
void CClassB::CConstrucL() // Khởi tạo pha 2 : có thể leave {
iX = new (ELeave) CClassX; }
Lúc đó, khi sử dụng lớp CClassB sẽ thực hiện như sau : CClassB *iY = new (ELeave) CClassB; //Khởi tạo pha 1 CleanupStack::PushL(iY); iY->ConstrucL(); // khởi tạo pha 2 // Sử dụng iY ... // Hủy đối tượng iY: CleanupStack::Pop(iY);
Tìm hiểu công nghệ Bluetooth và viết ứng dụng minh họa