Jump to content
  • Advertisement
Sign in to follow this  
Decrius

[C++] Delete base class pointer which actually holds a derived class pointer?

This topic is 3709 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

Is this perfectly safe?
#include <iostream>

class CBase {};
class CDerived : public CBase {};

int main ()
{
    CBase* b = new CDerived;
    delete b;
    return 0;
}

I have an array of base pointers, which is filled with derived pointers of that base class. Is it safe to delete it? Should I cast it first to the derived class (how do I know which class I have filled it with? ^^). Unsure if it's safe, how would it know the size it has to deallocate? I still wonder how you can ever fill a base class pointer with a derived class pointer, they both differ in size, don't they? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
As long as your base class has a virtual destructor, this is fine.

Quote:

I still wonder how you can ever fill a base class pointer with a derived class pointer, they both differ in size, don't they?


A derived class is a base class. And you don't "fill" a pointer with an object, you point at an object with a pointer.

Share this post


Link to post
Share on other sites
Yea as far as I know the code is fine. You do not need to cast it, but the base class should have a virtual destructor.

Each compiler has it's own mechanism for determining what the size is. Don't worry about it !!

EDIT : damn .. to slow !!

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
so it's done at compiler time, not run time


What's done at compile time? Virtual dispatches are done at run-time.

Share this post


Link to post
Share on other sites
To see how making the destructor virtual makes a difference you might try this:


#include <iostream>
using std::cout;

struct A
{
A() { cout << "A()\n"; }
//virtual
~A() { cout << "~A()\n"; }
};

struct B: public A
{
B() { cout << "B()\n"; }
~B() { cout << "~B()\n"; }
};

int main()
{
A* p = new B;
delete p;
}





The B part of the object is never destructed and that's undefined behaviour.

Now comment in the virtual keyword. Now at run-time the destructor for both parts of *p are called, as the virtual keyword tells it to start destructing from the actual most derived type of *p and call all the destructors all the way up to that of the parent.

Share this post


Link to post
Share on other sites
So, a virtual is usefull for when you have a base class pointer filled with a derived class pointer?

As for the compiler-time, I referred to the sizes of what should be deallocated ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
So, a virtual is usefull for when you have a base class pointer filled with a derived class pointer?

As for the compiler-time, I referred to the sizes of what should be deallocated ;)


Once again, as Driv3MeFar already pointed out, you don't "fill" pointers. You allocate memory somewhere and the pointer points to the address in memory where that section begins.

Share this post


Link to post
Share on other sites
The problem isn't that he gets what you mean. The concern is that you may not quite understand what you're saying. They're trying to help. :)

If you "fill" a pointer with a value, then you would be treating the pointer as some form of data structure - a way to store various bits of information in memory in different ways.

What you need to understand is you're not actually "filling" the pointer. What you have is a pointer that contains a value, much like an integer or float contains a value. And, just like an integer, a pointer takes up a few bytes in memory (size varies based on your architecture, 16-bit, 32-bit, 64-bit, or whatever). These few bytes are only used to store a memory address. That's it, nothing else. This memory address is located completely separate of the pointer, at some random location in memory and you don't care where.

Quote:

As for the compiler-time, I referred to the sizes of what should be deallocated ;)


Again, no. Virtual functions are handled at run-time. As are allocations and deallocations. Consider:


#include <iostream>
using namespace std;

class A
{
public:
A() { cout << "A()" << endl; }
virtual ~A() { cout << "~A()" << endl; }
private:
};

class B : public A
{
public:
B() { cout << "B()" << endl; }
~B() { cout << "~B()" << endl; }
private:
};

int main()
{
char input;
A* obj;


cout << "Enter 1 or 2: ";
cin >> input;

if ( input == '1' ) { obj = new A; }
else { obj = new B; }

delete obj;

return 0;
}





You can enter 1 or 2. At compile time, the code doesn't know which variable obj will be allocated to when it calls delete. Nor does it care. It's handled at run time. This is even the case if you don't use virtual methods. However, to ensure your destructor is run for your derived class (and any other methods you may choose to override in the derived class that are in the base class), you need to be virtual.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • 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!