Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Do you find C#'s lack of an explicit destructor to be an issue?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
23 replies to this topic

#21 swiftcoder   Senior Moderators   -  Reputation: 10242

Like
1Likes
Like

Posted 17 August 2013 - 10:00 PM

Ok. Object 1 owns object 2. This is explicit. Object 3 has a reference to object 2 because it needs to work with some data it has. Object 1 dies, so it kills object 2 as well. This is also explicit.

 

The two statements marked in bold both represent potential problems with this design:

- Object 1's lifetime is non-deterministic by virtue of being garbage collected, so by tying object 2's lifetime to object 1, you have made object 2's lifetime non-deterministic as well.

- If object 3 stores a reference to object 2, then it has assumed co-ownership of object 2, and object 2 can no longer be solely tied to object 1's lifetime.

 

There are a couple of questions that are worthwhile to ask at this point:

- Why is the lifetime of object 2 tied to that of object 1, instead of being tied to program lifecycle events (i.e. level unload, application shutdown, etc)?

- Why does object 3 store a reference to object 2? Is the a concrete reason why it could not be passed that reference each time it needs access to the data?

- Why cannot object 3 maintain a reference to object 1 instead?


Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


Sponsor:

#22 Hodgman   Moderators   -  Reputation: 31210

Like
0Likes
Like

Posted 18 August 2013 - 02:00 AM

Ok. Object 1 owns object 2. This is explicit. Object 3 has a reference to object 2 because it needs to work with some data it has. Object 1 dies, so it kills object 2 as well.  This is also explicit. 
 
Nowwe still need to inform object 3 that it's reference to object 2 is no longer valid.

if you know ahead of time that the lifetime of #3 is shorter than #1/#2, then there's no problem (in debug builds, I'd use a weak reference and assert that it is never nullified).
If you know that the lifetime of #3 is longer than #2, then the ownership definition may be wrong.
If the lifetimes of #1 and #3 are arbitrary and unrelated, but you want to detach the link between #3/#2 when #1 dies, then use a weak-reference / weak-pointer, or write this behavior explicitly if it's regular business logic instead of resource management ;)

#23 Sacaldur   Members   -  Reputation: 531

Like
0Likes
Like

Posted 18 August 2013 - 03:18 AM

There was an sprite-drawing-example similar to the 3 objects.
I don't see any problems in drawing sprites in C# (or Python, or Java, ...).
In general you will have some kind of ingame environment, eg. a map, a level, a room, or something else. This environment contains all the objects you want to draw, walls, tables, charakters, items, mosnters, and so on. So why don't you try to draw the environment and store the sprites seperated?
There are also other problems arising out of this bad design: the player opens a door and an other sprite has to be drawn at the same position, the player starts walking, the player hides and gets invisible, an item explodes and there has to be some kind of explosion effect, or the drawing order changes (because the player walked behind a wall).
This way you would have to add and remove sprites all the time. By drawing the environment you could always use the objects current states and removing(/destroying) an object is no problem.

#24 dmatter   Crossbones+   -  Reputation: 3262

Like
1Likes
Like

Posted 18 August 2013 - 06:19 AM

My point is that In a managed language like C# there is extra implementation to be done.

And my point is that you should be doing this implementation in C++, too. Skating by with shared ownership semantics only takes you so far.

Ok. Object 1 owns object 2. This is explicit. Object 3 has a reference to object 2 because it needs to work with some data it has. Object 1 dies, so it kills object 2 as well.  This is also explicit. 
 
Nowwe still need to inform object 3 that it's reference to object 2 is no longer valid.

I am a bit confused about how you think C++ handles this any better than C#?

If Object 3 and Object 1 owned shared_ptrs to Object 2 then you'll have the same cleanup considerations as with C#.
If Object 3 owned a weak_ptr then C# has those too, but with a non-deterministic GC I wouldn't bother, nor would I go that route in C++ either.
If Object 3's lifetime or its reference to Object 2 is short, transient or non-owning (e.g. you re-pass Object 2 along every frame), then you can do that in C# as well.

The only thing I can think at the moment is that your destructor of either Object 1 or Object 2 will call directly into Object 3 to unregister Object 2? If so you have still had to put that 'extra implementation' into C++ too, only in a destructor. Hopefully Object 3 would never through an exception during that unregistering.

A C++ destructor (or C# IDisposable) is really about cleaning up raw resources within that object - not about supporting your business logic to unregister it from the rest of the system.

Edited by dmatter, 18 August 2013 - 06:26 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS