我什么时候使用哪种指针? >好,所以我上次写C++的生存, STD::AutoMyPTR < /C> >所有STD LIB都可用,而Booo::SyrdYPPTR 非常流行。我从未真正研究过boost提供的其他智能指针类型。我知道C++11现在提供了boost提出的一些类型,但不是所有类型
那么,是否有人有一个简单的算法来确定何时使用哪个智能指针?最好包括关于哑指针(原始指针,如我什么时候使用哪种指针? >好,所以我上次写C++的生存, STD::AutoMyPTR < /C> >所有STD LIB都可用,而Booo::SyrdYPPTR 非常流行。我从未真正研究过boost提供的其他智能指针类型。我知道C++11现在提供了boost提出的一些类型,但不是所有类型,c++,pointers,c++11,smart-pointers,c++-faq,C++,Pointers,C++11,Smart Pointers,C++ Faq,那么,是否有人有一个简单的算法来确定何时使用哪个智能指针?最好包括关于哑指针(原始指针,如T*)和其他boost智能指针的建议。(像这样的东西就太好了) 始终使用unique\u ptr,除非需要参考计数,在这种情况下,使用shared\u ptr(对于非常罕见的情况,弱\u ptr,以防止参考循环)。几乎在所有情况下,可转让的唯一所有权都是可以接受的 原始指针:只有当您需要协变返回时才好,这是可能发生的非拥有指针。否则它们就没什么用处了 数组指针:unique\u ptr具有对T[]的专门化,
T*
)和其他boost智能指针的建议。(像这样的东西就太好了) 始终使用unique\u ptr
,除非需要参考计数,在这种情况下,使用shared\u ptr
(对于非常罕见的情况,弱\u ptr
,以防止参考循环)。几乎在所有情况下,可转让的唯一所有权都是可以接受的
原始指针:只有当您需要协变返回时才好,这是可能发生的非拥有指针。否则它们就没什么用处了
数组指针:unique\u ptr
具有对T[]
的专门化,它会自动对结果调用delete[]
,因此您可以安全地执行unique\u ptr p(新的int[42])代码>例如shared_ptr
您仍然需要一个自定义的deleter,但不需要专门的共享或唯一数组指针。当然,这些东西通常最好用std::vector
来代替。不幸的是,shared\u ptr
没有提供数组访问功能,因此您仍然需要手动调用get()
,但是unique\u ptr
提供了操作符[]
而不是操作符*
和操作符->
。无论如何,你必须检查自己。这使得shared_ptr
的用户友好性稍差,尽管可以说,通用优势和无增强依赖性使得unique_ptr
和shared_ptr
再次成为赢家
作用域指针:通过unique\u ptr
变得不相关,就像auto\u ptr
一样
struct ListNode
{
std::shared_ptr<ListNode> m_next;
std::weak_ptr<ListNode> m_prev;
};
真的没什么了。在没有移动语义的C++03中,这种情况非常复杂,但在C++11中,建议非常简单
其他智能指针仍有使用,如侵入式\u ptr
或进程间\u ptr
。但是,它们非常适合,在一般情况下完全没有必要。决定使用哪种智能指针是一个所有权问题。在资源管理方面,如果对象A控制对象B的生存期,则对象A拥有对象B。例如,成员变量由其各自的对象拥有,因为成员变量的生存期与对象的生存期相关联。您可以根据对象的所有权选择智能指针
请注意,软件系统中的所有权与所有权是分开的,因为我们认为它不属于软件。例如,一个人可能“拥有”他们的家,但这并不一定意味着人
对象可以控制房子
对象的生命周期。将这些真实世界的概念与软件概念相结合,是将自己编程到一个洞中的一种可靠方法
如果您拥有对象的唯一所有权,请使用std::unique\u ptr
如果您共享了对象的所有权…
-如果所有权中没有周期,请使用std::shared\u ptr
-如果存在循环,则定义一个“方向”,并在一个方向上使用std::shared_ptr
,在另一个方向上使用std::weak_ptr
如果对象拥有您,但可能没有所有者,请使用普通指针T*
(例如父指针)
如果对象拥有您(或以其他方式保证存在),请使用引用T&
警告:请注意智能指针的成本。在内存或性能受限的环境中,只使用普通指针和更手动的内存管理方案可能会有好处
费用:
- 如果您有一个自定义删除程序(例如,您使用分配池),那么这将导致每个指针的开销,手动删除可以轻松避免
std::shared_ptr
的开销是复制时参考计数增加,销毁时减少,然后进行0计数检查并删除保留的对象。根据实现的不同,这可能会使代码膨胀并导致性能问题
- 编译时。与所有模板一样,智能指针对编译时间有负面影响
示例:
struct BinaryTree
{
Tree* m_parent;
std::unique_ptr<BinaryTree> m_children[2]; // or use std::array...
};
在这里,列表节点拥有其下一个和上一个列表,因此我们定义了一个方向,并对下一个使用shared\u ptr
,对上一个使用weak\u ptr
,以打破循环。共享所有权:
所采用的共享ptr
和弱ptr
标准与他们的标准基本相同。当你需要共享一个资源,但不知道哪一个是最后一个活着的资源时,可以使用它们。使用弱\u ptr
观察共享资源,而不影响其生命周期,而不是中断周期。通常不应发生共享\u ptr
的循环-两个资源不能相互拥有
请注意,Boost还提供了其他功能,这可能是shared\u ptr
的合适替代方案
struct ListNode
{
std::shared_ptr<ListNode> m_next;
std::weak_ptr<ListNode> m_prev;
};
接下来,Boost提供了一个轻量级的解决方案,如果您的资源已经提供了引用计数管理,并且您希望将其应用于RAII原则,那么它就是一个轻量级的解决方案。该标准未采用该标准
唯一所有权:
Boost还有一个不可复制且不能为其指定删除程序的std::unique_ptr
是类固醇上的boost::scoped_ptr
,当您需要智能指针时,它应该是您的默认选择。它允许您在其模板参数中指定一个删除器,并且是可移动的,与boost::s不同