C++ - shared_ptr<vector<T>> 与 vector<shared_ptr<T>> 的区别

6
我看到很多人使用vector<shared_ptr<T>>。何时和为什么会使用shared_ptr<vector<T>>呢?对我来说,后者在性能和内存使用方面似乎更有效率。在应用程序中共享单个对象向量是错误的吗?
谢谢

6
std::vector<std::shared_ptr<T>> 表示共享指针的向量,而 std::shared_ptr<std::vector<T>> 则表示一个向量的共享指针。两者有很大的区别。 - Some programmer dude
3
不要将新的智能指针视为“指针”,而应从所有权的角度来看待它。指针一次只能被一个“用户”拥有,还是可以同时被多个“用户”拥有? - Some programmer dude
有没有任何情况下会使用 std::shared_ptr<std::vector<T>>?(这种类型假定动态分配了一个 std::vector,而动态分配 std::vector 的情况非常罕见。) - James Kanze
除了那不编译,至少对于g++而言是如此。(当然,我假设通常的g++选项,包括-D_GLIBCXX_CONCEPT_CHECKS。当然,它将无法在某些未来的标准版本中编译;概念的目标是使其成为需要诊断的错误。) - James Kanze
1
@JamesKanze:啊,好吧,这本书有一个构造函数QueryResult(string s, shared_ptr<set<line_no>, shared_ptr<vector<string>>>),并将指针复制到成员变量中。另外,我同意它容易被误解,特别是那些来自Java/C#的人,但更普遍的是,想要为容器使用shared_ptr的所有合法原因与单个数据的原因并没有太大区别——容器的生命周期需要解耦和所有权分散... - Tony Delroy
显示剩余5条评论
1个回答

8

使用 vector<shared_ptr<T>> 可以让你将类型为 T 的实例从该向量传递给代码的其他部分,而无需担心它们是否会被释放。即使你的向量不再存在。

另一方面,shared_ptr<vector<T>> 仅保护向量本身,其元素(类型为 T)不受内存泄漏的保护。我假设这里的 T 是指针类型,如果 T 不是指针,则在此处制造内存泄漏就不是问题了。当然,有人可能会实际上将 T = shared_ptr<T>

实际上,更常见的是使用 vector<shared_ptr<T>>,我真的不记得使用过 shared_ptr<vector<T>>

关键在于,在代码中永远不要保留分配的内存的裸指针,始终将它们保存在某种智能指针中。如果使用 RAII 实现自己的分配/释放机制,也是完全可以的。


最后一句话完全没有意义。很多情况取决于应用程序,但在大多数使用动态内存的应用程序中,我希望大多数指针都是用于导航,并且应该是原始指针。 - James Kanze
@JamesKanze 我改了最后一句话,我的意思是指向已分配的内存的指针。 - marcinj
但这并不改变任何事情。在许多应用程序中(我所工作的大部分应用程序),动态分配的原因是所涉及的对象的生命周期由程序逻辑确定。这意味着智能指针不合适。 - James Kanze
我不确定我是否理解了 - 你是说"智能指针"不适用于"动态分配"吗? - marcinj
在你的代码中,绝对不能保留指向已分配内存的裸指针,这是过分夸张的说法。但显然它的意图是指应该使用“拥有”指针来释放内存。动态分配意味着生命周期与分配范围无关,但你可以返回智能指针,并让它冒泡到负责持续拥有的范围,而几乎没有额外开销。有些人认为这是良好的编程风格,对我来说,无论哪种方式都没有特别的问题。 - Tony Delroy
2
我应该将其命名为“指向已分配内存的指针,如果丢失将导致泄漏,如果未得到安全管理将导致失眠”。 - marcinj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接