4

现在,我的 C++ 项目中的对象所有权/删除是手动跟踪的(主要通过注释)。几乎每个堆分配的对象都是使用各种工厂创建的

例如

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

在这种情况下,智能指针会提供什么好处(如果有的话)?

4

3 回答 3

9

您应该担心的不是创建,而是删除。

使用智能指针(引用计数类型),对象可以由其他几个对象共同拥有,并且当最后一个引用超出范围时,该对象会被自动删除。这样,您将不必再手动删除任何内容,只有在具有循环依赖关系时才能泄漏内存,并且您的对象永远不会从背后的其他地方删除。

单一所有者类型 ( std::auto_ptr) 也免除了您的删除责任,但它一次只允许一个所有者(尽管所有权可以转移)。这对于您作为指针传递的对象很有用,但您仍然希望它们在超出范围时自动清理(以便它们在容器中正常工作,并且在异常情况下展开的堆栈按预期工作)。

在任何情况下,智能指针都会在您的代码中明确所有权,不仅对您和您的队友,而且对编译器 - 做错可能会产生编译器错误或相对容易捕获的运行时错误防御性编码。在手动内存管理的代码中,很容易在某处弄错所有权情况(由于误读注释,或以错误的方式假设事情),并且由此产生的错误通常很难追踪 - 你会泄漏内存,覆盖东西那不是你的,程序随机崩溃等等;这些都有一个共同点,即发生错误的情况与有问题的代码部分无关。

于 2010-12-17T12:06:52.070 回答
2

智能指针强制执行所有权语义——也就是说,即使在出现异常的情况下,也可以保证对象将被正确释放。出于安全考虑,您应该始终使用它们,即使它们只表达非常简单的语义,例如 std::unique_ptr。此外,强制语义的指针减少了记录它的需要,更少的文档意味着更少的文档过时或不正确——尤其是在同一程序的多个部分表达相同语义的情况下。

最终,智能指针减少了许多错误来源,几乎没有理由不使用它们。

于 2010-12-17T12:41:21.097 回答
1

如果一个对象仅由另一个对象拥有,并随它而死,那很好。仍然需要确保没有悬空引用,但这不是难事。

最困难的情况是您共享所有权。在这种情况下,您将需要 smart-ptrs(或其他东西)来自动确定何时实际删除对象。

请注意,并非所有地方都需要共享所有权,当您的产品变得臃肿时,避免它可能会简化事情。:)

于 2010-12-17T12:16:59.807 回答