Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

GamerSg

Inherited Objects Deconstructors

This topic is 5532 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Try declaring the base class destructor virtual. It seems like that has come up for me before and that worked.

class blah{
public:
blah();
virtual ~blah();
};

Share this post


Link to post
Share on other sites
I still use my base class to define other objects so i cannot declare it''s deconstructor virtual.

Im not sure what virtual does but i think it''s supposed to be empty.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Hmm i tried the protected function. It compiled and worked.

But when i exited the application, i got an error pointing to the line

/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

in dbgdel.cpp.





Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!