🔒 Locked
Inherited Objects Deconstructors
Advertisement
Original Post
OK, ill try to keep this as simple as possible.
Say i have a base class for 3d objects.
This class is mainly used to load up models and display them onscreen.
Now i inherited a Player class from the base class. I intend to allow the player class to have other properties like hp,mana, and other functions and variables.
Since different models have different number of vertices, textures, etc.., i dynamically allocate memory during the loading process. The data is then deleted via the deconstructor.
Now that i have a derived class, i can use the load,display functions without any problems. But my question is whether the base class deconstructor is called when the player class is destroyed or do i have to specify all the delete commands again the player class deconstructor. I cant seem to be able to do this, because the pointer is private in the base class and the deconstructor of the Player class doesnt seem to have access to it.
quote:
Original post by GamerSg
I still use my base class to define other objects so i cannot declare it''s deconstructor virtual.
Sure you can.
quote:
Im not sure what virtual does but i think it''s supposed to be empty.
Virtual functions allow derived classes to specify their own implementation of the functions, including destructors. The catch is, as you have to worry about, is that sometimes you want a derived class to use the base class''s implementation. Here are three options:
1. duplicate the code in the derived class''s function (YUCKY, DON''T DO THIS).
2. In the base class, create a ''protected'' function that handles the code you want shared (in this case, the deallocation), and DON''T make this virtual. Then just call this function from both destructors. (YUMMY, DO THIS).
3. Call the base class destructor from the derived class destructor, just by calling BaseClass::~BaseClass(); inside your DerivedClass destructor. Can lead to a few weird complications if you''re not careful.
That could be any of a million things.
Basically, you have a memory problem, likely trying to free the same memory twice. If you''re using the protected, non-virtual cleanup function in the base class (called from the destructor) to delete the memory, the base class destructor should still be virtual, and the derived class destructor should NOT call the base class destructor but instead call the protected cleanup function.
If you''re sure you''re doing that right, than the error could be anything, it''s hard to tell without the code. Easiest would be for you to run it in a debugger, and then when you hit the error, look at the call stack to see which variable of yours, and where it is used, is causing the problem and then start tracing backwards.
If you''re sure you''re doing that right, than the error could be anything, it''s hard to tell without the code. Easiest would be for you to run it in a debugger, and then when you hit the error, look at the call stack to see which variable of yours, and where it is used, is causing the problem and then start tracing backwards.
Ok i ran it in debug mode and to my surprise,
the derived class''s deconstructor was called first.
Nothing unsual here.
So it called the protected cleanUp();
But, after it had cleaned up, it went on to call the base class deconstructor even though i have not called the deconstructor or specified any base class object.
the derived class''s deconstructor was called first.
Nothing unsual here.
So it called the protected cleanUp();
But, after it had cleaned up, it went on to call the base class deconstructor even though i have not called the deconstructor or specified any base class object.
quote:
Original post by BriTeg
the base class destructor should still be virtual, and the derived class destructor should NOT call the base class destructor but instead call the protected cleanup function.
From my knowledge, the derived class does not inherit the deconstructor of the base class. So am i right to say that it need not be virtual.
And from my debugging, i realise that the derived class automatically calls the base class deconstructor.
Pls correct me if im wrong.
Another qsn: If you did not delete a block of memory, would the OS clear up after u exit the application.
Hokey crap, I''ve led you down the garden path. I whipped up a quick test program, and it looks like I was completely wrong. The derived class''s destructor *will* call the base class destructor, regardless if it is virtual or not. This is not how other member functions work, I guess it''s only for the destructor.
So, forget everything I said.
Delete your stuff in your base class destructor (or even keep that protected cleanup function, it''s handy if you want to reset your object without destroying it), and make your derived contructor completely empty (unless the derived class does extra memory allocation of its own).
Sorry again for the wrong information, I feel bad.
So, forget everything I said.
Sorry again for the wrong information, I feel bad.
Let''s take an example : class B inherits from A.
Whether the destructors are virtual or not, whenever B::~B()
is called, A::~A() is called right after. So you do NOT have
to reimplement A::~A() in B::~B().
Now, here''s what the virtual destructor changes. Say you write the following code :
A* a = new B();
delete a;
If both destructors are virtual, "delete a" will invoke B::~B(). If they are not, "delete a" will invoke A::A() (which is probably not what you want).
There is a simple rule : if there are virtual methods in a class (or in its base class) the destructor must be defined virtual.
Hope it helps.
Whether the destructors are virtual or not, whenever B::~B()
is called, A::~A() is called right after. So you do NOT have
to reimplement A::~A() in B::~B().
Now, here''s what the virtual destructor changes. Say you write the following code :
A* a = new B();
delete a;
If both destructors are virtual, "delete a" will invoke B::~B(). If they are not, "delete a" will invoke A::A() (which is probably not what you want).
There is a simple rule : if there are virtual methods in a class (or in its base class) the destructor must be defined virtual.
Hope it helps.
quote:
Original post by BriTeg
Hokey crap, I''ve led you down the garden path. I whipped up a quick test program, and it looks like I was completely wrong. The derived class''s destructor *will* call the base class destructor, regardless if it is virtual or not. This is not how other member functions work, I guess it''s only for the destructor.
So, forget everything I said.Delete your stuff in your base class destructor (or even keep that protected cleanup function, it''s handy if you want to reset your object without destroying it), and make your derived contructor completely empty (unless the derived class does extra memory allocation of its own).
Sorry again for the wrong information, I feel bad.![]()
Lol.
It''s OK. Thx for the help anyway. I would probably have been sleeping(Midnite now) if you had not replied to my post and i would never have solved this.
quote:
Original post by rodzilla
Let''s take an example : class B inherits from A.
Whether the destructors are virtual or not, whenever B::~B()
is called, A::~A() is called right after. So you do NOT have
to reimplement A::~A() in B::~B().
Now, here''s what the virtual destructor changes. Say you write the following code :
A* a = new B();
delete a;
If both destructors are virtual, "delete a" will invoke B::~B(). If they are not, "delete a" will invoke A::A() (which is probably not what you want).
There is a simple rule : if there are virtual methods in a class (or in its base class) the destructor must be defined virtual.
Hope it helps.
So virtual deconstructors are only required if you use polymorphism in ur app?
Im not comfortable with polymorphism and i cant think of a reason why anyone would need it when inheritance can do it.It would be nice to tell me the advantages of polymorphism over inheritance.
Only one rule : whenever you use virtual methods, the destructor must be virtual.
As for using polymorphism, say you have "drawable" things. Some
"drawable"s will be, say, "model"s. Other "drawable"s could be, say, "particle_systems".
When you will render your "drawable"s, there are 2 options :
- you put all "drawable"s in a list (of drawable*) and the draw methods must be virtual.
- the draw methods are non-virtual and you have to use separate strong-typed lists (a list of model*, a list of particle_system*...).
This example is probably not relevant, but I hope you get the idea.
Be careful anyway, calling a virtual method has a tiny cost.
It''s probably not a good thing to make a million virtual calls per frame.
As for using polymorphism, say you have "drawable" things. Some
"drawable"s will be, say, "model"s. Other "drawable"s could be, say, "particle_systems".
When you will render your "drawable"s, there are 2 options :
- you put all "drawable"s in a list (of drawable*) and the draw methods must be virtual.
- the draw methods are non-virtual and you have to use separate strong-typed lists (a list of model*, a list of particle_system*...).
This example is probably not relevant, but I hope you get the idea.
Be careful anyway, calling a virtual method has a tiny cost.
It''s probably not a good thing to make a million virtual calls per frame.
quote:
Original post by rodzilla
Only one rule : whenever you use virtual methods, the destructor must be virtual.
One question though: if you use virtual methods in your base class, those methods in your derived class are virtual whether or not you specify "virtual" explicitly. Why does this not also happen for destructors?
I''m not sure there''s a good reason for this.
Of course, the destructor is a very special method, because
when you call it (via delete or when exiting a block), all destructors in the class hierarchy will be invoked.
BTW, when redefining a virtual method (in a child class), you should use the "virtual" keyword. It doesn''t change anything as far as the compiler is concerned, but it make the code more readable.
Of course, the destructor is a very special method, because
when you call it (via delete or when exiting a block), all destructors in the class hierarchy will be invoked.
BTW, when redefining a virtual method (in a child class), you should use the "virtual" keyword. It doesn''t change anything as far as the compiler is concerned, but it make the code more readable.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement