Resource Acquisition is Initialization
I was once asked in an interview what my favourite feature of C++ was to which I immediately responded "destructors". The interviewer retorted that garbage collection made destructors redundant. Looking back I assume that he was pushing me to give further explanation of what made destructors such a neat feature which I didn't manage to give immediately but I did explain in the context of boost::mutex::scoped_lock later on.
Lately working with C# has brought me back to the feeling that deterministic destruction is a great feature. In C# resources are destroyed using the dispose pattern
1 2 3 4 5 6 7 8 9 | MyConnection connection = null; try { connection = new MyConnection(foo); connection.Open(); // Make use of the connection here } finally { // Only today I encountered code where the null check was forgotten :( if (connection != null) { connection.Dispose(); } } |
this is made significantly less painful by the using keyword:
1 2 3 4 | using (var connection = new MyConnection(foo)) { connection.Open(); // Use connection here, disposed when we leave the using block } |
but it still relies on the caller to remember that instances of this class need special attention. In addition when there are multiple resources in use things can get a little messy (although nothing compared to Java which lacks the using keyword).
Back in the C++ world things are much simpler:
1 2 | MyConnection connection(foo); // use connection here, it will be destroyed when it goes out of scope |
and this same pattern applies to all resources: files, memory, mutex locks, whatever. Not to mention the fact that it scales well to multiple objects. There is just something inherently elegant about solving the general case of resource management with one technique rather than the combination of garbage collection and the lock and using keywords.
Comments
No comments.
Post a comment
Markdown syntax can be used in comments.