现在,我的C ++项目中的对象所有权/删除是手动跟踪的(通过评论)。几乎每个堆分配的对象都是使用排序工厂
创建的e.g。
auto b = 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
智能指针在这种情况下会提供什么好处?
答案 0 :(得分:9)
这不是你应该担心的创作,而是删除。
使用智能指针(引用计数类型),对象可以共同拥有其他几个对象,当最后一个引用超出范围时,将自动删除该对象。这样,您就不必再手动删除任何内容了,只有当您具有循环依赖关系时才能泄漏内存,并且您的对象永远不会从您背后的其他地方删除。
单一所有者类型(std::auto_ptr
)也可以减轻您的删除义务,但它一次只允许一个所有者(尽管可以转让所有权)。这对于作为指针传递的对象很有用,但是当它们超出范围时仍然希望它们自动清理(这样它们在容器中运行良好,并且在异常情况下展开的堆栈按预期工作)。
在任何情况下,智能指针都会在您的代码中明确所有权,不仅对您和您的团队成员,而且对编译器也是如此 - 做错了可能会产生编译器错误或运行时错误相对容易接受防御性编码。在手动内存管理的代码中,很容易在某处弄错所有权情况(由于误读评论或假设方法错误),并且产生的错误通常难以追踪 - 你会泄漏内存,覆盖东西这不是你的,程序随机崩溃等;这些都是共同的,发生错误的情况与违规代码部分无关。
答案 1 :(得分:2)
智能指针强制执行所有权语义 - 也就是说,即使在异常的情况下也能保证正确释放对象。你应该总是因为安全性而使用它们,即使它们只表达非常简单的语义,例如std :: unique_ptr。此外,强制语义的指针减少了记录它的需要,而较少的文档意味着较少的文档过时或不正确 - 特别是在同一程序的多个部分表达相同语义的情况下。
最终,智能指针可以减少许多错误来源,并且没有理由不使用它们。
答案 2 :(得分:1)
如果一个对象仅由另一个对象拥有,并且随之死亡,那么很好。仍然需要确保没有悬空引用,但这不是困难的情况。
困难的情况,是您分享所有权的地方。在这种情况下,您需要使用智能ptrs(或其他内容)自动确定何时实际删除对象。
请注意,在任何地方都不需要共享所有权,并且当产品变得臃肿时,避免它可能会简化事情。 :)