3 ms·
Hmm. I don't agree with this conclusion. Take for instance a file class in C++ which opens the file descriptor in the constructor and closes it in the destructo
by strictfp 15y ago
Hmm. I don't agree with this conclusion. Take for instance a file class in C++ which opens the file descriptor in the constructor and closes it in the destructor. Now, for any instance of this class, it is impossible for the open fd to outlive the instance!. That is an as strong guarantee as I need! Now, if I leak the instance the fd will leak too, but that is more an issue of manual lifecycle management if you ask me.
This very significant property is what makes me love RAII. I don't count C#'s using-statement and/or rubys block statement as RAII since it relies on useage patterns. C++'s automatic destruction of graphs of objects also makes it outshine all other methodologies, and the guaranteed destruction is the key here.
- vidarh 15y agoRAII is a usage pattern: You must stack-allocate an object or wrap it in a suitable smart pointer. It's just as easy to do things differently as it is with Ruby's blocks or C#'s using statement. The reason it has a name is because it is a pattern that's talked about so much exactly because following the pattern is so intrinsic to modern C++ programming. Once you're passing a block to a method like this in Ruby, the execution of the cleanup code is just as guaranteed as it is in C++.
- strictfp 15y agoI don't agree completely. As I said, you cannot leak the fd without leaking the memory of the object. This means that in C++ you get the correct behavior as long as you take care of the lifecycle of your objects correctly. You don't need to do stack allocation or smart pointers as long as you de-allocate the object when your are done with it. So the lifetime of the fd is tightly bound to the lifetime of the wrapper instance. If you stack allocate without deallocation you have a bug _anyway_ in your C++ program, thus I would like to argue that it is a problem of manual lifecycle management, not a flaw in the RAII implementation. You do however have a point when you say that you can miss deallocation and that is just as easy as forgetting to put a variable in a block. In an ideal world I would like to be able to decouple de-allocation time from destruction time, as someone mentioned above they are completely orthagonal issues. If this would be possible, one could guarantee the destructor callback, but defer deallocation until later. This would probably give leeway to more effective memory allocation patterns while keeping RAII alive. And another thing about blocks: how do you deal with trees and graphs of objects? That is not trivial when using blocks. You can get around it, but continuing that way would most likely lead you to something like Haskells monads (the "programmable semicolon" aspect of them).