标签: shared-ptr

C++中的空和空std :: shared_ptr有什么区别?

cplusplus.com shared_ptr页面召唤出一个区分 std::shared_ptr shared_ptr.该cppreference.com页面没有明确叫出区别,但同时使用"空",并比较nullptr其描述std::shared_ptr行为.

空和空之间有区别shared_ptr吗?这种混合行为指针有用例吗?非空null是否shared_ptr有意义?是否会出现正常使用情况(即如果你没有明确构造一个),你最终会得到一个空但非空的shared_ptr

如果您使用的是Boost版本而不是C++ 11版本,那么这些答案中的任何一个都会改变吗?

c++ shared-ptr c++11

75
推荐指数
2
解决办法
1万
查看次数

将shared_ptr <Derived>作为shared_ptr <Base>传递

shared_ptr派生类型传递给采用shared_ptr基类型的函数的最佳方法是什么?

我通常通过shared_ptr引用传递s以避免不必要的副本:

int foo(const shared_ptr<bar>& ptr);
Run Code Online (Sandbox Code Playgroud)

但如果我尝试做类似的事情,这不起作用

int foo(const shared_ptr<Base>& ptr);

...

shared_ptr<Derived> bar = make_shared<Derived>();
foo(bar);
Run Code Online (Sandbox Code Playgroud)

我可以用

foo(dynamic_pointer_cast<Base, Derived>(bar));
Run Code Online (Sandbox Code Playgroud)

但这似乎是次优的,原因有两个:

  • dynamic_cast对于简单的派生到基础演员来说,A 似乎有点过分.
  • 据我了解,dynamic_pointer_cast创建一个指向传递给函数的副本(虽然是临时的).

有更好的解决方案吗?

后人更新:

原来这是一个缺少头文件的问题.此外,我在这里尝试做的是一个反模式.通常,

  • 不影响对象生命周期的函数(即对象在函数持续时间内保持有效)应采用普通引用或指针,例如int foo(bar& b).

  • 使用对象的函数(即,是给定对象的最终用户)应该采用unique_ptrby值,例如int foo(unique_ptr<bar> b).std::move调用者应该将值放入函数中.

  • 延长对象生命周期的函数应采用shared_ptrby值,例如int foo(shared_ptr<bar> b).避免循环引用的通常建议适用.

有关详细信息,请参阅Herb Sutter的回归基础讲座.

c++ casting smart-pointers shared-ptr c++11

74
推荐指数
4
解决办法
5万
查看次数

static_cast with boost :: shared_ptr?

什么是一个相当于static_castboost::shared_ptr

换句话说,我该如何重写以下内容

Base* b = new Derived();
Derived* d = static_cast<Derived*>(b);
Run Code Online (Sandbox Code Playgroud)

什么时候用shared_ptr

boost::shared_ptr<Base> b(new Derived());
boost::shared_ptr<Derived> d = ???
Run Code Online (Sandbox Code Playgroud)

c++ boost shared-ptr static-cast

72
推荐指数
2
解决办法
4万
查看次数

shared_ptr和weak_ptr差异

我正在阅读Scott Meyers的"Effective C++"一书.有人提到有内置指针tr1::shared_ptrtr1::weak_ptr行为,但它们跟踪tr1::shared_ptrs指向对象的数量.

这称为引用计数.这在防止非循环数据结构中的资源泄漏方面效果很好,但是如果两个或多个对象包含tr1::shared_ptrs形成循环,则循环可以使彼此的引用计数保持在零以上,即使所有指向循环的外部指针都已被破坏.

那是tr1::weak_ptrs进来的地方.

我的问题是循环数据结构如何使引用计数高于零.我恳请一个示例C++程序.问题是如何解决的weak_ptrs?(再次,请举例).

c++ shared-ptr weak-ptr cyclic-reference c++11

69
推荐指数
4
解决办法
5万
查看次数

我应该从使用boost :: shared_ptr切换到std :: shared_ptr吗?

我想在GCC中启用对C++ 0x的支持-std=c++0x.我并不一定需要GCC 4.5中的任何当前支持的C++ 11功能(很快就会有4.6),但我想开始习惯它们.例如,在我使用迭代器的一些地方,auto类型会很有用.

但同样,我不需要任何当前支持的功能.这里的目标是鼓励我将新标准的特征融入我的编程"词汇"中.

根据您对C++ 11支持的了解,在GCC中启用它是一个好主意,然后通过例如从使用切换boost::shared_ptrstd::shared_ptr专用来实现它,因为两者不混合?

PS:我知道这个比较不同口味的好问题,shared_ptr但是我要求在标准最终确定之前提出更高级别的建议.另一种说法是,当像GCC这样的编译器说它支持"实验性功能"时,这是否意味着我可能会在编译过程中遇到奇怪的错误,这些错误将成为主要的时间汇,并且是StackOverflow上一个神秘问题的来源?

编辑:我决定退回,std::shared_ptr因为我只是不相信它在GCC 4.5中的支持,如本问题中的示例所示.

c++ boost stl shared-ptr c++11

66
推荐指数
4
解决办法
3万
查看次数

为什么没有std :: shared_ptr <T []>专门化?

该标准提供了一个模板特化std::unique_ptr,正确调用delete[]其析构函数:

void func()
{
   std::unique_ptr< int[] > arr(new int[10]);

   .......
}
Run Code Online (Sandbox Code Playgroud)

由于std::shared_ptr这种专业化不可用,因此有必要提供一个正确调用的删除器delete[]:

void func()
{
    // Usage
    shared_ptr array (new double [256], [](double* arr) { delete [] arr; } ); 

    ..............
}
Run Code Online (Sandbox Code Playgroud)

这只是一个疏忽吗?(以同样的方式存在std::copy_if)或是否有原因?

c++ shared-ptr c++11

64
推荐指数
1
解决办法
9851
查看次数

为什么unique_ptr在shared_ptr只占用一个时会占用两个模板参数?

双方unique_ptrshared_ptr接受定制的析构函数他们所拥有的对象上调用.但在的情况下unique_ptr,析构函数作为一个模板参数传递,而类型shared_ptr的自定义析构函数将被指定为一个模板参数的构造函数.

template <class T, class D = default_delete<T>> 
class unique_ptr
{
    unique_ptr(T*, D&); //simplified
    ...
};
Run Code Online (Sandbox Code Playgroud)

template<class T>
class shared_ptr
{
    template<typename D>
    shared_ptr(T*, D); //simplified
    ...
};
Run Code Online (Sandbox Code Playgroud)

我不明白为什么会有这样的差异.需要什么?

c++ std shared-ptr unique-ptr c++11

63
推荐指数
1
解决办法
3714
查看次数

如何将一个std :: shared_ptr投降?

考虑:

struct SomethingThatsABase
{
    virtual bool IsChildOne() const { return false; }
    virtual bool IsChildTwo() const { return false; }
};

struct ChildOne : public SomethingThatsABase
{
    virtual bool IsChildOne() const { return true; }
};

struct ChildTwo : public SomethingThatsABase
{
    virtual bool IsChildTwo() const { return true; }
};

void SomeClientExpectingAChildOne(std::shared_ptr<ChildOne> const& ptrOne)
{
    //Does stuff
}

void SomeClient(std::shared_ptr<SomethingThatsABase> const& ptr)
{
    if (ptr->IsChildOne())
    {
        SomeClientExpectingAChildOne(ptr); //Oops.
        //Hmm.. can't static_cast here, because we need a `shared_ptr` out of …
Run Code Online (Sandbox Code Playgroud)

c++ shared-ptr downcast c++11

62
推荐指数
3
解决办法
4万
查看次数

C++ 11清除shared_ptr时,我应该使用reset还是设置为nullptr?

我有一个关于C++ 11最佳实践的问题.清除shared_ptr时,我应该使用reset()没有参数的函数,还是应该设置shared_ptrnullptr?例如:

std::shared_ptr<std::string> foo(new std::string("foo"));
foo.reset();
foo = nullptr;
Run Code Online (Sandbox Code Playgroud)

是否存在任何真正的差异,或者两种方法都存在优势/劣势?

c++ reset shared-ptr nullptr c++11

58
推荐指数
2
解决办法
6万
查看次数

传递shared_ptr的成本

我在整个应用程序中广泛使用std :: tr1 :: shared_ptr.这包括在函数参数中传递对象.考虑以下:

class Dataset {...}

void f( shared_ptr< Dataset const > pds ) {...}
void g( shared_ptr< Dataset const > pds ) {...}
...
Run Code Online (Sandbox Code Playgroud)

虽然通过shared_ptr传递数据集对象可以保证它在f和g中的存在,但是这些函数可能会被调用数百万次,这会导致很多shared_ptr对象被创建和销毁.这是最近一次运行的平坦gprof配置文件的片段:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls   s/call   s/call  name
  9.74    295.39    35.12 2451177304     0.00     0.00  std::tr1::__shared_count::__shared_count(std::tr1::__shared_count const&)
  8.03    324.34    28.95 2451252116     0.00     0.00  std::tr1::__shared_count::~__shared_count()

因此,大约17%的运行时用于使用shared_ptr对象进行引用计数.这是正常的吗?

我的应用程序的很大一部分是单线程的,我正在考虑重写一些函数

void f( const Dataset& ds ) {...}
Run Code Online (Sandbox Code Playgroud)

并替换电话

shared_ptr< Dataset > pds( new Dataset(...) );
f( pds …
Run Code Online (Sandbox Code Playgroud)

c++ performance shared-ptr

57
推荐指数
2
解决办法
2万
查看次数