Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我什么时候使用哪种指针? >好,所以我上次写C++的生存, STD::AutoMyPTR < /C> >所有STD LIB都可用,而Booo::SyrdYPPTR 非常流行。我从未真正研究过boost提供的其他智能指针类型。我知道C++11现在提供了boost提出的一些类型,但不是所有类型_C++_Pointers_C++11_Smart Pointers_C++ Faq - Fatal编程技术网

我什么时候使用哪种指针? >好,所以我上次写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不同