开发者

Manual Object Ownership vs Smart Pointers

Right now, object ownership/deletion in my C++ project is manually tracked (via comments mostly). Almost every heap allocated object is created using a factory of sorts

e.g.

auto 开发者_如何学JAVAb = a->createInstanceOfB(); //a owns b
auto c = b->createInstanceOfC(); //b owns c
//auto k = new K(); //not in the code
...
//b is no longer used..
a->destroyInstanceOfB(b); //destroyInstanceOf calls delete on it

What benefits, if any, will smart pointers provide in this sitution?


It's not the creation you should worry about, it's the deletion.

With smart pointers (the reference counting kind), objects can be commonly owned be several other objects, and when the last reference goes out of scope, the object is deleted automatically. This way, you won't have to manually delete anything anymore, you can only leak memory when you have circular dependencies, and your objects are never deleted from elsewhere behind your back.

The single-owner-only type (std::auto_ptr) also relieves you of your deleting duty, but it only allows one owner at a time (though ownership can be transferred). This is useful for objects that you pass around as pointers, but you still want them automatically cleaned up when they go out of scope (so that they work well in containers, and the stack unrolling in the case of an exception works as expected).

In any case, smart pointers make ownership explicit in your code, not only to you and your teammates, but also to the compiler - doing it wrong is likely to produce either a compiler error, or a runtime error that is relatively easy to catch with defensive coding. In manually memory-managed code, it is easy to get the ownership situation wrong somewhere (due to misreading comments, or assuming things the wrong way), and the resulting bug is typically hard to track down - you'll leak memory, overwrite stuff that's not yours, the program crashes at random, etc.; these all have in common that the situation where the bug occurs is unrelated to the offending code section.


Smart pointers enforce ownership semantics- that is, it's guaranteed that the object will be freed correctly even in the case of exceptions. You should always use them purely because of the safety, even if they express only very simple semantics such as std::unique_ptr. Moreover, a pointer that enforces the semantics reduces the need to document it, and less documentation means less documentation to be out of date or incorrect- especially where multiple parts of the same program express the same semantics.

Ultimately, smart pointers reduce many sources of error and there's little reason not to use them.


If an object is only owned by one other object, and dies with it, fine. Still need to make sure there's no dangling references, but this is not the hard case.

The hard case, is where you share ownership. In that case, you will want to have smart-ptrs (or something) to automatically figure out when to actually delete an object.

Note that shared ownership is not necessary everywhere, and avoiding it will likely simplify things down the road when your product goes bloaty. :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜