3

Does the delete() operator destroy all the sub-objects of an object too? Or do I need to call the delete of sub-object before deleting the parent object?

class equipment
{
   public:
     int model_id;
     ...
}

class player
{
   public:
     int x, y;
     equipment * Equipment; 
     player(void) { Equipment = new equipment[2];};
     ~player(void) { delete [] Equipment; }
};

int main (....)
{
  player = new Player;
  ...
  ...
  delete Player;
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Wracker
  • 589
  • 10
  • 32

5 Answers5

3

you need to delete the dynamically allocated subobjects in the destructor of the main object and you have properly done this by deleting array Equipment

fatihk
  • 7,789
  • 1
  • 26
  • 48
  • Thanks for your quick response, is there any way I could actually check whether the sub-object was properly deleted from the memory? – Wracker Jun 24 '13 at 08:10
  • 1
    @Wracker: Just being careful when designing/implementing the class, or using an idiom to avoid care of that. For example: if you alway and only allocate memory in the constructor, you know you have to deallocate in the destructor; otherwise, you have to be sure the pointer is null when memory is not allocated and check it before deallocate; or you can use smart pointers (like `unique_ptr` or `shared_ptr`) to not worry about deallocations when destructor or your class is invoked. – Gonmator Jun 24 '13 at 08:32
  • how come that the destructor for class "equipment" isn't being executed after calling `delete[] equipment`? – Wracker Jun 24 '13 at 09:47
  • @Wracker, destructors of equipment are called after calling delete[] – fatihk Jun 24 '13 at 10:05
  • ok it's working , just had a typo error in my code . Thanks for help! – Wracker Jun 24 '13 at 10:06
  • @Wracker - If you want to "see everything as it happens", just put temporary `cout << "Deleting player @" << this << '\n';` statements in all of your destructors (and similar ones in your constructors), and you can see it all... even stack objects (ones you didn't allocate with `new`). But be sure to declare all the constructors for a class (incl. default ctor & copy ctor), or else the compiler may create them automatically and those of course won't print a `cout` statement, so it might be confusing to see a `cout` for a destructor without a matching `cout` for a constructor of that object. – phonetagger Jun 25 '13 at 02:45
  • @Wracker - Note that just because you "declare" such constructors doesn't mean you have to "define" them.... you could declare them private & not ever define them, and the compiler or linker will tell you if your code ever tries to use them, at which point you can decide whether to define them or change the code that uses them such that it doesn't require the undefined constructor. – phonetagger Jun 25 '13 at 02:48
  • @phonetagger: Nowadays we just add `= delete` to the declaration of such unwanted members. That catches unintended use even within the class itself. – MSalters Jun 25 '13 at 09:56
  • @MSalters - Must be a C++11 thing. We're only using C++11 on one of our many projects, and I've not had a chance to get very familiar with it yet. Thanks! – phonetagger Jun 25 '13 at 14:33
2

Delete operator does delete all "subobjects" as you say, but usually and in your case you need to delete not only "sub objects" but also memory, where member pointers point to. So if you used vector object, for example, it would be deleted automatically, but in this case you need to delete it explicitly, which you did correctly

sasha.sochka
  • 14,395
  • 10
  • 44
  • 68
1

To put it simply, during destruction of the object :

  • Member objects are themselves destroyed
  • Objects pointed by member pointers aren't

That means that you have to delete them manually (like your Equipement pointer), if you own them. There might be case when your class ends up with a pointer it does not own (for example, a handle to some other object you need in this class), and thus should not delete.

You can use smart pointers (i.e.:std::shared_ptr, std::unique_ptr, etc.) to manage memory in a safer way (they, notably, automatically delete the pointers they manage, following the RAII principle ).

JBL
  • 12,588
  • 4
  • 53
  • 84
0

One thing you are missing is the destructor in class equipment

Vijay
  • 65,327
  • 90
  • 227
  • 319
0

The stuff you do in your example is sufficient, you

delete[] Equipment;

in the destructor of player, so all contained equipments will be deleted as soon as a player gets deleted.

Nicely done!

Xie
  • 374
  • 1
  • 8
  • well the things is, after I deleted the Equipment object, i can still access its data . ~player(void) { delete [] Equipment; std:;cout<model_id; } I mean it prints out the model_id as if the object was still in memory. – Wracker Jun 24 '13 at 08:41
  • But the memory can be used for other stuff now - and could be changed then. Just try to new another object afterwards - chances are good that you get exactly the same memory address. The memory does not get deleted, just marked as "not used anymore". – Xie Jun 24 '13 at 08:53
  • @Wracker: You can access an deleted object, but that is undefined behaviour. When you delete the object the memory gets freed. This does not mean the bits get overwritten. They are around until something is using the memory location. But you don't own that memory space anymore. – Skalli Jun 24 '13 at 15:13