-
Posts
2,953 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Blog Comments posted by Roland
-
-
HA! Thats exactly what I did in first LEO-versions (or did I ever send them? ), those which were rejected because they did not follow the C-API exactly. Well, thats history and its a great way of storing and loading thigs. Good reading
-
Haha .. Yeah Theo. We are apparently saying the same thing. But your are right of course. I those cases where you don't intend you make your class inheritable the virtual things are of course not needed at all. Would be nice to have a 'final' keyword in C++
-
Seeing this thing develop promises a good 2012
-
Oh ... and regarding the "[#10136] You do not have permission to report the item you are attempting to report."
I have seen that for weeks now. Nothing to bother about, the post works anyway.
-
I removed the correction
Seems that I don't have to kill my self after all
-- case 1: No virtuals
#include <iostream> using namespace std; class Base { public: Base() { cout<<"Constructor: Base"<<endl;} ~Base() { cout<<"Destructor : Base"<<endl;} }; class Derived: public Base { public: Derived() { cout<<"Constructor: Derived"<<endl;} ~Derived() { cout<<"Destructor : Derived"<<endl;} }; void main() { Base *Var = new Derived(); delete Var; }
Output
Constructor: Base
Constructor: Derived
Destructor : Base
Press any key to continue . . .
Only Base destructor called.... ERROR!!!
-- case 2: Base destructor virtual (this is what I said)
#include <iostream> using namespace std; class Base { public: Base() { cout<<"Constructor: Base"<<endl;} virtual ~Base() { cout<<"Destructor : Base"<<endl;} }; class Derived: public Base { public: Derived() { cout<<"Constructor: Derived"<<endl;} ~Derived() { cout<<"Destructor : Derived"<<endl;} }; void main() { Base *Var = new Derived(); delete Var; }
Output
Constructor: Base
Constructor: Derived
Destructor : Derived
Destructor : Base
Press any key to continue . . .
All destructors called - OK
-- case 3: Derived destructor virtual
#include <iostream> using namespace std; class Base { public: Base() { cout<<"Constructor: Base"<<endl;} ~Base() { cout<<"Destructor : Base"<<endl;} }; class Derived: public Base { public: Derived() { cout<<"Constructor: Derived"<<endl;} virtual ~Derived() { cout<<"Destructor : Derived"<<endl;} }; void main() { Base *Var = new Derived(); delete Var; }
Output
Constructor: Base
Constructor: Derived
Destructor : Base
Then ----> Crash : ERROR
So my statment seems valid. If you ever has a reason to believe that your class will be inherited you should have a virtual base class destructor. Maybe the school was right then
-
Sorry, but that's what you say to school developers in the first year C++ . There is a huge performance impact as from you have 1 virtual function. It should actually be the other way around, If you inherit or want you class to be inherited from, make your destructor virtual...ALWAYS MAKE DESTRUCTORS VIRTUAL if you not has a good reason no to.A(){ _pmem = new char[1024];}A():_pmem(new char[1024]){ } //No default initialization. Modern compilers should optimize this...
So you mean that I was wrong !!! How embarrasing
Well then there is only one thing to do - As you are completely right I have to go a kill my self
-
Inititalizing ...
Do that in the constructors. Then if you feel better to do your resorce allocations etc etc.. in a method (there can be reasons for that) you should make it a virtual method.
class A { char* _pmem; public: A() : _pmem(nullptr) {} virtual ~A() { DeInit(); } virtual void Init() { DeInit(); _pmem = new char[1024]; } virtual void DeInit() { delete [] _pmem; _pmem = nullptr; } }; class B : public A { char* _pMoreMem; public: B() : _pMoreMem(nullptr) {} virtual ~B() { DeInit(); } virtual void Init() { __super::Init(); DeInit(); _pMoreMem= new char[256]; } virtual void DeInit() { __super::DeInit(); delete [] _pMoreMem; __pMoreMem = nullptr; } }; void somewhere() { A a; B b; a.Init(); // A's init will be called b.Init(); // B's init will be called (which the internally calls A's init) a.Deinit(); // a's memory will be deleted } // end of scope. // a's memory is already deleted so nothing will happen // b's memory will be deleted including the part allocated by A // If you had missed the virtual keyword for the destuctors, A's desctructor would never have been executed and you would have a memory leak
In case you allocate your class resources in a Init method I would recommend having a public virutal void DeInit() also and call that from the destructor.
About virtual destructors. In case you have any belief that your class will ever be inherited you MUST make the destructor virtual. And as its very hard to know what the needs are going to be in the future I would say. ALWAYS MAKE DESTRUCTORS VIRTUAL if you not has a good reason no to.
Keeping things in the constructors and destructors make things a bit more easy although it might not always be in line with you want.
class A { char* _pmem; public: A() { _pmem = new char[1024]; } virtual ~A() { delete [] _pmem; } }; class B : public A { char* _pMoreMem; public: B() { _pMoreMem= new char[256]; } virtual ~B() { delete [] _pMoreMem; } }; void somewhere() { A a; // a will be created and its memory allocated B b; // b will be created and its memory include the A-part will be allocated } // end of scope. // a's memory is deleted in its destructor // b's memory is deleted in its destructor, The A-part destructor will also be called as its virtual
EDIT: Sorry Theo ... you wrote an answer while I was typing.. so I guess I just repeted some.
-
Ok Mumbles, I understand. Its just the way you like to have it and have full respect for that.
Good post
-
Interesting techniuqe and well written.
One little statement of no direct importance for the technique described, but still not correct.
But it can be re-written without a class, whilst still keeping the access specifiers. "How?" You might ask, because it's true that public, protected and private (well, and friend too) are all class access specifiers - they can't be used for structs or namespaces. Well, here's how:
A class is same thing as a struct with one and only one difference. The class protection is by default private, while its by default public for the struct. The code below is fully valid as the struct and class is essential the same thing.
struct MyStruct { MyStruct() : _prot(0), _priv(0) {} protected: int _prot; void prot() {} private: int _priv; void priv() {} };
Anyway. What's described here is an interesting way of solving the need for statics. So according to this LEO::Draw could be rewritten to something like this (not tested) if one would like to, although this is kind of "hidden" C-programming
namespace LEO { namespace Draw { void SetColor( const TVec3& color ); void SetColor( const TVec4& color ); void SetColor( flt red, flt green, flt blue, flt alpha = 1 ); void SetBlend( int blendmode ); void Clear( void ); void Plot( int x, int y ); void Line( int x1, int y1, int x2, int y2 ); void Rect( int x, int y, int width, int height ); void Image( const Texture& image, int x, int y, int width = -1, int height = -1 ); void Text( int x, int y, const_str text, ... ); } }
Question
One question about this arrangement. What is gained by using this namespace technique instead of a static class. I can't see in what way this improve things other than the semantics. Have I missed something or is it just about semantics?
-
Thank's Josh. Good review
-
Thanks a lot Naughty. This is a given bookmark for me
-
Just of curiosity. Is there any special reason why you doesn't use enumerations like this
enum CollisionType { COLLISON_NONE, COLLISION_SCENE, COLLISION_CHARACTER, COLLISION_PROP, COLLISION_DEBRIS }; void PhysicsDriver::SetCollisionResponse(const CollisionType& collisiontype0, const CollisionType& collisiontype1, const int& response) { if ( collisiontype0 == COLLISION_SCENE ) .... .... .... }
-
Most inspiring reading
-
Looks great to me AnniXa. The idea with a simple image based GUI is quite good. I did that in some demo some years ago. The whole GUI was not one image though. In my case each button was an own image, but essential it was done in the same style and it work very good.
Having a full fledged GUI with buttons, dragbars, checkboxes and good knows what can be overkill for most games, where its just a matter of give the user some simple information and the ability to select och click on some choices.
Keep up the good work
-
Nice work Metatron
-
Great. This is exiting news
-
Have just started making apps for Android and this is exiting news
-
Looking good and the idea of comprehensive examples sounds good to me.
-
Great
-
Wow Marleys Ghost. Thats is just awesome.
Congratulations to that achivement... Your 3rd Person camera is just outstanding good. Any plans to share ;)
-
Great of you to keep the headers up-to-date with various environments
-
Oh my Oh my.... Besides buying a MAC I now must by a IPhone
-
Looks great, and the name Leadwerks.Extensions.Awesomium... that is so cool
-
Haven't come to using particles yet, but this looks great.
Must bookmark this one so I don't forget later on.
Moving Right Along...
in Development Blog
A blog by Josh in General
Posted
Think this feature will really be a hit.