Understanding newl constructl newlc eleave
When you are a beginner in Symbian development, the first thing you are confused about is cleanupstack. The second is newl, newlc, and constructl, which must be everywhere.
The appearance of these functions is still related to memory leakage. This is a two-step structure mechanism called two-phase construction.
I know that the new operator in C ++ actually completes two tasks. First, allocate a block of memory on the heap based on the size of the object class and obtain
Pointer. Second, use the pointer to call the class constructor and return the pointer.
There is a hidden danger in doing so on Symbian, that is, when you allocate the memory, but the program unexpectedly exits when calling the constructor, this will cause
The allocated memory generated a leak. Only the memory that is put into cleanupstack will be released after the program unexpectedly ends, and the new memory exists.
The constructor has not been put into cleanupstack yet.
To solve this problem, Symbian designers designed a programming formula for all developers.Two-phase construction.
Specifically:
The general new operation is divided into two steps. The first step is to allocate only the memory. After the allocated memory is put into cleanupstack, the second step is constructed.
But how can we prevent the new operation of the compiler from calling constructor in C ++? This does not seem to work...
As a result, the Symbian designer makes a rule that the class should not do any operations that may generate exceptions in the constructor, but only do absolutely safe things, such
Assign values to simple variables, and then provide a function named constructl to initialize all classes in this function, including of course the dangers.
May cause abnormal operations.
Then the Symbian class structure becomes like this.
For example, there is a class named cfoo. I want to declare a pointer P and create a cfoo object and assign it to P.
Cfoo * P = new (eleave) cfoo ();
Cleanupstack: pushl (P );
P-> constructl ();
Cleanupstack: Pop ();
Is writing like this a little cool? Each object must be created with four statements. It is too troublesome to use it frequently.
As a result, the designers of Symbian made another rule. Each class should implement a newl static function to complete the work of the above four statements.
Class cfoo
{
Public:
Static cfoo * newl ()
{
Cfoo * Self = new (eleave) cfoo ();
Cleanupstack: pushl (Self );
Self-> constructl ();
Cleanupstack: Pop ();
Return self;
}
}
With newl, the program that calls the cfoo class is simplified.
Cfoo * P = cfoo: newl ();
So what is newlc? What is the difference with newl?
Some classes are like this. They provide some methods that need to be executed after the object is created, but these methods also produce exceptions, such
Cfoo if there is a method called dosomethingl ()
Can the program be written like this?
Cfoo * P = cfoo: newl ();
P-> dosomethingl ();
Obviously, this is the correct way to write the code.
Cfoo * P = cfoo: newl ();
Cleanupstack: pushl (P );
P-> dosomethingl ();
Cleanupstack: Pop ();
Oh, my God, there are four more statements, which is too troublesome. You know, at the end of newl, we just pulled the cfoo pointer from cleanupstack and immediately put it in again.
Can it be simplified? Well, we can save two more statements.
Newl removes the ending cleanupstack: Pop ();
Static cfoo * newl ()
{
Cfoo * Self = new (eleave) cfoo ();
Cleanupstack: pushl (Self );
Self-> constructl ();
Return self;
}
Call to remove cleanupstack: pushl
Cfoo * P = cfoo: newl ();
P-> dosomethingl ();
Cleanupstack: Pop ();
The designers of Symbian also stipulated that newl with the above behavior should be called newlc. It indicates that the pointer is not retrieved from cleanupstack after it is returned. You can continue to call a dangerous operation and call cleanupstack: Pop () at the end ();
I found that newl can be implemented by calling newlc.
So a class that complies with the N rules of the Symbian designer should be written in this way.
Class cfoo
{
Public:
Static cfoo * newlc ()
{
Cfoo * Self = new (eleave) cfoo ();
Cleanupstack: pushl (Self );
Self-> constructl ();
Return self;
}
Static cfoo * newl ()
{
Cfoo * Self = newlc ();
Cleanupstack: Pop ();
Return self;
}
Virtual ~ Cfoo ()
{
}
Protected:
Cfoo ()
{
}
Void constructl ()
{
//....
}
}
Note that the cfoo constructor cannot be public. To prevent users from using new or creating objects on the stack.
The Destructor should be written as a virtual function. This is a pure C ++ problem and cannot be understood.More effective tive C ++
It should be noted that the above method is strongly recommended by Symbian, but it is not a hard rule. You only need to ensure that there is no memory leakage
This can be avoided.
I personally recommend that such code be well understood by anyone who writes Symbian programs.
Finally, let's talk about why there is a new (eleave ).
The new operator is overloaded by Symbian, and eleave is a parameter for new, which means to tell New when memory cannot be allocated
The program exits. For example, when the memory is insufficient.
So if we use eleave, we don't have to check the pointer returned by new. It must be correct if we can return it.
If an error occurs, the program will end, and new will not return.
Newl newlc is a symbolic function of the Symbian program, so a resource site developed by Symbian is calledWww.newlc.com