Regarding pointers which are members of classes. Should they be of a smart pointer type or is it enough to simply deal with them in the destructor of the class they are contained in?
- Anybody can ask a question
- Anybody can answer
- The best answers are voted up and rise to the top
No, it's not enough to deal with the raw pointer in the destructor. You also have to deal with it in the copy constructor and assignment operator functions. It's usually not enough to simply copy the pointer (which the compiler will happily do for you); you probably really want to make a copy of the resource it points to. And you have to remember to gracefully handle self-assignment without leaking the resource. Maybe you don't want to support copying at all, so you have to remember to explicitly disable those functions. Maybe you want to give out handles to that resource, so you have to keep track of when it's safe to be freed. What if an exception is thrown in the middle of your constructor? What if you aren't the one throwing it? Maybe there's another edge case I haven't thought of.
(Note: I've debugged more than enough of this kind of code that gets it wrong, hence my somewhat harsh tone.)
If you want to get it right on the first try, then yes, you should go with a smart pointer type such as
Well if they are only members, I prefer not bother with delete and use boost::scoped_ptr. For me that's the simpler way to manage it.
Now, if you don't have access to boost, or don't want to use it, you can make you own simple smart pointer that simply does the delete for you in it's destructor. It's really easy and I let you do it as an exercise, if you need it.
In the end, only if I'm "forced" to I'll use delete in the destructor of the owner class. The problem is that I know it will change in the future and if we wait enough, it will change in a way that will make the delete wrong. When that happen, nobody will remember there was a delete, until it crashes...
So, it's better to setup the destruction rule at the creation or definition point instead of somewhere else in the code base (somewhere nobody will remember because it's far from the definition point).
That's why we use smart pointers where we can.
As always, it's not a good idea to use smart pointers for everything, but in this specific case, if your member is only created at owner construction and destroyed at owner destruction, make your life easy, use a smart pointer.