Recently, one of the developers that work for me got highly animated while pointing out an issue with the C++ code of another developer on the team. Without all the emotional buildup, it can be summarized as a class is allocated using new with a reference to a containing class passed into the constructor. The constructor adds itself (this) to the collection class and exits. The containers destructor contains all the logic to actually delete the elements it contains. This code works. There are no memory leaks. Some readers may already know. It was all about scope.
While he was pointing this out, I was remembering an age old rule that I always follow. I have been following it so long that I never even think of why I follow it. The rule is simple: All creation and deletion must happen at the same level of scope. Now before the purists go nuts on me, there are exceptions or more likely interpretations - as there are to most rules. One such stretch of the rule is smart pointers. I consider smart pointers to actually contain the pointer, usually by putting the allocation in the constructor of the smart pointer. This makes smart pointers a follower of this rule through liberal interpretation. There are also times when it is necessary to do some pointer ownership transfers. These are exceptions and require a significant amount of comments in the code to be maintainable. The last of the big three (there are others, but these three are the big ones I have run across) is COM. COM allocates in the factory, and deletes in the release. Two different scopes and thus an exception due to ownership transfer. So moving past these points, I have always strived to ensure that all allocations and deallocations happen in the same scope. This scope being liberally interpreted as meaning not just the method scope, but potentially two methods in the same class. This allows for the common database class methods of AddRow() which returns a new row and DeleteRow() which takes the row and actually deletes it.
Ok. So now that I stated one my rules, I returned to the conversation with my developer. He was livid over how unmaintainable the code is as written. I told him of my rule, of which he has heard of before, and he realized that this is exactly the type of code I was trying to avoid with this rule. After working with me for nearly four years, he finally knew why this rule existed. Prior to this, the rule was just something I said. Now he is a convert to the rule, following it because he believes rather my say so. Even the addition of a couple of methods for add and delete would have made the code easier to read and maintain despite more lines of code.
His epiphany was amusing to see. It reminded me of my own some years back while coding in C using the Turbo C compiler. I find the same rule still applies to nearly all other resources and in the age of managed code. While I am not allocating and deallocating memory, I am acquiring and releasing resources. Overall this rule is one my all time favorites and has saved me significant grief from maintaining crappy code.
I just thought I would share it. Comments? Opinions?