Re: Stack and Heap
Ian Collins wrote:
May be! One can do it happily in his Linux box. I am not as lucky as
you :(
I mostly program for embedded devices. And standard is not supported by
most of the compilers. There the practical thumb rule is, use template
as less as you can, though it may look a bad idea! One can't entirely
blame the system also, as implementing template for C++ (also C++ in
general) is very difficult job for compiler writers, as the language is
very ambiguous from compiler writer's perspective, esp template (I have
enough experience from my past job :) ) .Thus it is not strange that
they don't implement many of the standard features.
The popular frameworks like wxWidgets or Qt don't support template
mostly because, if they do so, the supported platform will get reduced
to less than half of what they do now.
The second problem is the kind of generic programming template offers
is somewhat different than OO generics. Many prefer single rooted
object hierarchy rather than template meta-programming (like most of
the existing frameworks).
The problem with template is that it do not respect object hierarchy
(unlike Java generics) .Thus one can write,
XYZFile button = window.createWi dget<XYZFile>(" OK");
Compiler will happily accept it if it found a matched ctor, or matched
methods which are called. But the whole system will behave abnormally,
as XYZFile know how to paint in a file, not in a window!
Instead, window.addWidge t(Widget& ) or window.addWidge t(Window* )
respect object hierarchy, and dont have such problem.
Thus usual way of writing in most of the cases,
1) Button* btn = new Button("OK"); //potential chance for memory lick,
if one doesn't do a delete or write the next line.
this->add(btn,AlignT op);
2) Button* btn = new Button("OK",thi s); //safer, no fear for memory
leak. but fear of deleting a pointer when it is owned by container.
like delete btn;
3) ref<Buttonbtn = new Button("OK",thi s);// more safe
4) if your API don't support 2) or 3) kind of object creation (most of
them don't) , Use a factory for creating controls in the client code. I
usually use UIFactory, which has,
Button& createButton(co nst string& name, const string& image, Window*
parent){} etc.
where I usually add the two steps of component creation.
Only problem still persists here is, someone gets the reference to the
button inside window, passes it outside and kills the window! better to
pass a reference, which is counted (like smart pointer in your example)
That's the problem I set out to resolve when I took the "everything is a
self-contained object" approach.
>
One interesting side effect is that the C++ code is also valid Java,
JavaScript and (with the addition of a couple of '$'s) PHP. Which makes
coded generation a snip.
>
>
If Buttons are self-contained, the object management problems go away.
>
A valid technique, provided you don't expose the working to the user!
>
>
A big +1 to that.
>
Indeed, but don't forget we can do it better with RAII.
>
--
Ian Collins.
Ian Collins wrote:
toton wrote:
That's one way and a common on one for GUI toolkits. The other is for
Element to be a self contained reference counted object. I find the
latter conceptually better and easier to implement.
>
Problem here. This should be client's code, and one defined in API, as
window doesn't know all of the components available, or about any 3rd
party component ( may be something like RoundedButton ?)
RoundedButton button = window.createWi dget<RoundedBut ton>("OK");
>
Should do the trick, I have a similar templated createElement<> () method
in my DOM Document class.
Ian Collins wrote:
It is possible, as document creates the element. Thus it can add a
reference to itself, and delete the object when it gets deleted.
>toton wrote:
>
>>The point was made, heap (free store) is not needed except C++ std
>>collections . There are a lot more than the std library. They all need
>>free store. Even users of those library needs free store.
>>
>
>I read the comment as not used directly, but still used indirectly.
>Which is true. One doesn't use new to create an object, rather one uses
some factory method to obtain a smart pointer object that wraps the object.
>
>The XML DOM code I use for web page generation used dynamic objects
>under the hood, but all my page generation uses statements like
>
>Element p = document.create Element("p");
>
>Element is a smart pointer type, document.create Element() is a factory
>method.
>
>>The point was made, heap (free store) is not needed except C++ std
>>collections . There are a lot more than the std library. They all need
>>free store. Even users of those library needs free store.
>>
>
>I read the comment as not used directly, but still used indirectly.
>Which is true. One doesn't use new to create an object, rather one uses
some factory method to obtain a smart pointer object that wraps the object.
>
>The XML DOM code I use for web page generation used dynamic objects
>under the hood, but all my page generation uses statements like
>
>Element p = document.create Element("p");
>
>Element is a smart pointer type, document.create Element() is a factory
>method.
reference to itself, and delete the object when it gets deleted.
Element to be a self contained reference counted object. I find the
latter conceptually better and easier to implement.
>
>>I see a problem with delete. But what is the problem with new? If one
>>needs dynamic memory , he needs new.
>>How will I add a Button in a Window when user clicks something?
>>either by Button* pButton = new ImageButton("OK ");
>
>or an interface like my DOM,
>
>Button buttom = window.createIm ageButton("OK") ;
>>needs dynamic memory , he needs new.
>>How will I add a Button in a Window when user clicks something?
>>either by Button* pButton = new ImageButton("OK ");
>
>or an interface like my DOM,
>
>Button buttom = window.createIm ageButton("OK") ;
window doesn't know all of the components available, or about any 3rd
party component ( may be something like RoundedButton ?)
>
Should do the trick, I have a similar templated createElement<> () method
in my DOM Document class.
you :(
I mostly program for embedded devices. And standard is not supported by
most of the compilers. There the practical thumb rule is, use template
as less as you can, though it may look a bad idea! One can't entirely
blame the system also, as implementing template for C++ (also C++ in
general) is very difficult job for compiler writers, as the language is
very ambiguous from compiler writer's perspective, esp template (I have
enough experience from my past job :) ) .Thus it is not strange that
they don't implement many of the standard features.
The popular frameworks like wxWidgets or Qt don't support template
mostly because, if they do so, the supported platform will get reduced
to less than half of what they do now.
The second problem is the kind of generic programming template offers
is somewhat different than OO generics. Many prefer single rooted
object hierarchy rather than template meta-programming (like most of
the existing frameworks).
The problem with template is that it do not respect object hierarchy
(unlike Java generics) .Thus one can write,
XYZFile button = window.createWi dget<XYZFile>(" OK");
Compiler will happily accept it if it found a matched ctor, or matched
methods which are called. But the whole system will behave abnormally,
as XYZFile know how to paint in a file, not in a window!
Instead, window.addWidge t(Widget& ) or window.addWidge t(Window* )
respect object hierarchy, and dont have such problem.
Thus usual way of writing in most of the cases,
1) Button* btn = new Button("OK"); //potential chance for memory lick,
if one doesn't do a delete or write the next line.
this->add(btn,AlignT op);
2) Button* btn = new Button("OK",thi s); //safer, no fear for memory
leak. but fear of deleting a pointer when it is owned by container.
like delete btn;
3) ref<Buttonbtn = new Button("OK",thi s);// more safe
>Yes, that would be the preferred way if you are using raw pointers.
them don't) , Use a factory for creating controls in the client code. I
usually use UIFactory, which has,
Button& createButton(co nst string& name, const string& image, Window*
parent){} etc.
where I usually add the two steps of component creation.
Only problem still persists here is, someone gets the reference to the
button inside window, passes it outside and kills the window! better to
pass a reference, which is counted (like smart pointer in your example)
self-contained object" approach.
>
One interesting side effect is that the C++ code is also valid Java,
JavaScript and (with the addition of a couple of '$'s) PHP. Which makes
coded generation a snip.
>
Infact people are creazy! I have seen someone who reuses common Buttons
(like OK Cancel etc) instead of creating them each time the dialog or
window needs it. They creates them first time, cache them, if many
window asks, returns a copy, and reference count them, and clear cache
upon request!
(like OK Cancel etc) instead of creating them each time the dialog or
window needs it. They creates them first time, cache them, if many
window asks, returns a copy, and reference count them, and clear cache
upon request!
If Buttons are self-contained, the object management problems go away.
>
I sometimes don't allocate memory for objects, when time comes, init it
in the pre-created memory pool (placement new) , use it, and destory
(deinitialize) after that. They are very light, as the major part ,
like memory allocation is done in a pool. Many character renderer use
that technique also. Alternative may be a pre-created object pool, and
change the object itself using setters, but looks little ugly.
in the pre-created memory pool (placement new) , use it, and destory
(deinitialize) after that. They are very light, as the major part ,
like memory allocation is done in a pool. Many character renderer use
that technique also. Alternative may be a pre-created object pool, and
change the object itself using setters, but looks little ugly.
>
Ultimately, it boils down to the fact, that everything can't be treated
same way. May be for most of the cases stl, standard smart ptr etc
works, but still some special case always exist which needs to be
treated differently. And there is beauty of C++ lies, one can take
precise control of the system, if one needs to do so.
same way. May be for most of the cases stl, standard smart ptr etc
works, but still some special case always exist which needs to be
treated differently. And there is beauty of C++ lies, one can take
precise control of the system, if one needs to do so.
A big +1 to that.
>
Simple Java like create & forget approach is not always good (Java has
a sofisticated gc and memory management, which C++ lacks), a little
"personal touch" is sometimes necessary :) .
a sofisticated gc and memory management, which C++ lacks), a little
"personal touch" is sometimes necessary :) .
>
--
Ian Collins.
Comment