I did some C recently. I remembered stuff like no classes, having to use the keyword struct all the time, and declaring all your variables at the start of a function. The thing I'd forgotten was just how you did things in C. Anytime you allocate anything, you have to catch every possible exit to the function to make sure it's deleted no matter what.
In C++, you have wrapper objects on the stack, and you can be certain that no matter what the destructors will be called on any kind of exit from the function (and the block) and clean up whatever it's wrapping. And not just for memory. The same technique works well for file handles, network sockets, thread safety, or just access to internal data structures, anything you like that you wouldn't want to get stuck in some kind of open state.
So in the name of progress, I'm doing some C# (and C++/CLI, but that's a different story). You can't create objects on the stack any more, you have to create them on the heap with new. And even though at the end of the block there's no references to the object, you can't count on when it might be destroyed, which means you can't be sure when the access to the file / socket / internal data structure is closed. A bit of a major problem, if say for example, you opened a file with exclusive access. That file would stay locked and subsequent access to the file would fail.
If you need to be sure of when whatever the object is managing is cleaned up, you can do it by calling Dispose, but then you're back to the C technique of having to make sure every possible exit from a function (including exceptions) calls Dispose. You've lost one of the major benefits of object oriented programming.
There's another problem. A common C++ technique is to use reference counting, and a "last one to leave turn out the lights" approach. You could have 5 references to the same file, and when the last reference is released (i.e. it's wrapper goes out of scope), the file is closed. C# promises to give you the same, except having had to call Dispose() on one of the references, the other four now all point to what is essentially a dead object. There's no way to have the cleanup happen when the last reference is released other than waiting for the garbage collection to call finalize, but that's not something you can rely on.
So you can't use Dispose and maintain multiple references to the same object, but you have to use Dispose if you ever want to be sure of proper cleanup. The only solution I can think of is to try to engineer the code in a way that you know where the last reference will be and only call Dispose for that reference, or of course implement reference counting (which would be ironic).
Is this a step backwards, or is it just me?
In C++, you have wrapper objects on the stack, and you can be certain that no matter what the destructors will be called on any kind of exit from the function (and the block) and clean up whatever it's wrapping. And not just for memory. The same technique works well for file handles, network sockets, thread safety, or just access to internal data structures, anything you like that you wouldn't want to get stuck in some kind of open state.
So in the name of progress, I'm doing some C# (and C++/CLI, but that's a different story). You can't create objects on the stack any more, you have to create them on the heap with new. And even though at the end of the block there's no references to the object, you can't count on when it might be destroyed, which means you can't be sure when the access to the file / socket / internal data structure is closed. A bit of a major problem, if say for example, you opened a file with exclusive access. That file would stay locked and subsequent access to the file would fail.
If you need to be sure of when whatever the object is managing is cleaned up, you can do it by calling Dispose, but then you're back to the C technique of having to make sure every possible exit from a function (including exceptions) calls Dispose. You've lost one of the major benefits of object oriented programming.
There's another problem. A common C++ technique is to use reference counting, and a "last one to leave turn out the lights" approach. You could have 5 references to the same file, and when the last reference is released (i.e. it's wrapper goes out of scope), the file is closed. C# promises to give you the same, except having had to call Dispose() on one of the references, the other four now all point to what is essentially a dead object. There's no way to have the cleanup happen when the last reference is released other than waiting for the garbage collection to call finalize, but that's not something you can rely on.
So you can't use Dispose and maintain multiple references to the same object, but you have to use Dispose if you ever want to be sure of proper cleanup. The only solution I can think of is to try to engineer the code in a way that you know where the last reference will be and only call Dispose for that reference, or of course implement reference counting (which would be ironic).
Is this a step backwards, or is it just me?
Comment