CBase operator new on a class on the stack
| Mon, 2006-02-06 18:00 | |
|
One of the few things that I've liked about Symbian is the overridden operator New of the CBase class. It sets all of your member variables to 0 or NULL, so you don't have to worry about setting all of your member variables yourself in the constructor(s).
However, if I have a CBase class on the stack, such as: Code: class CClass : CBase { public: void DoSomething() private: int iX; // expect this to be 0 on creation since this is CBase class char* iY; // ... ditto ... }; // ... MyMethod() { CClass myClass1; myClass1.DoSomething(); // member variables NOT init'ed CClass* myClass2; myClass2 = new(ELeave) CClass; // member variables init'ed myClass2->DoSomething(); } In the DoSomething() method, myClass1's member variables are not set to 0. This seems counterintuitive to me. If I cannot rely on the fact that CClass's variables will always be set to 0, I have to go back in all of my CBase class constructors, and put in the member variable initilization in there anyways! Making CBase's overriding the new operator misleading (and potentially dangerous, since your variables are initialized only some of the time!) Is there something I'm missing here! -euroq |
|






Forum posts: 92
Yes. C classes should never be stack-based. You must always create them on the heap.
Forum posts: 78
You must declare leaving function with the L letter, you must always "Close" R-classes, you must instantiate C-classes only on the heap, etc.
And one more rule. It is not that strict, nevertheless, you should not use new (Eleave) operator at all, you should keep the constructor protected and use the factory functions NewL and/or NewLC for instantiation.
I cannot recall it clearly, but I think, that CBase constructor is also protected
Compilable Symbian Code Examples
Forum posts: 149
So, quick question: Does anyone who writes Symbian programs ever make classes that don't follow the rules of C, R, and T classes? After all, if I don't have a Close() method it's not an R-class. If I want a simple storage class, but it holds its own heap data (owns its own pointers), it can't be a T class.
Seems rather inefficient to take the code that once used classes on the stack, and change them to heap, since the memory allocation just wastes time.
Forum posts: 78
Allocates memory = C-class and that's it. Of course, if you want to use the CleanupStack protection against memory leaks
You don't have to allocate everything on the heap. You can keep everything allocated on stack and then you don't need cleanup stack. It is not recommended practice since Symbian devices usually have very small stack size, but if it just about couple of ints, you can do it.
Compilable Symbian Code Examples
Forum posts: 149
So, just to clarify:
CClass myClass1;
myClass1.DoSomething(); // member variables NOT init'ed
}
... Is extremely against Symbian "conventions" and the real answer to my original question is, you just aren't supposed to do that... you can, but when you break conventions you have problems like I mentioned with the CBase new operator not being called to clear out your member variables.
Thanks everyone,
-euroq
Forum posts: 92
So T classes are any classes that can safely be created on the stack because they are leave safe. C classes are those that cannot be. You can break the rule and put a C class object on the stack if you can guarantee it will not leak if a leave occurs.
In effect, you either prevent leaves from occurring (ie use TRAPs or never call leaving code) or you make the class leave safe by not taking ownership of other objects (ie, it becomes the same as a T class).
If you break the rules you also have to guarantee that your callers understand this, and that anyone maintaining the code in future knows it too. It's just too much hassle really, and this is the reason why the convention is there. Not to restrict you, but so no misunderstandings occur
Forum posts: 124
CSomeclass* myInstance = new (ELeave)CSomeClass;
CleanupStack::PushL(myInstance);
blah blah
CleanupStack::PopAndDestroy(); // myInstance