标签: shared-ptr

如何实现std :: tr1 :: shared_ptr?

我一直在考虑使用共享指针,我知道如何自己实现它 - 不想这样做,所以我在尝试std::tr1::shared_ptr,我有几个问题......

引用计数是如何实现的?它是否使用双向链表?(顺便说一句,我已经用Google搜索了,但我找不到任何可靠的东西.)

使用它有任何陷阱std::tr1::shared_ptr吗?

c++ tr1 shared-ptr

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

是使用shared_ptr.reset还是operator =?

我试图围绕C++ 11的新习语.

似乎至少使用shared_ptr,使用new T()和之间存在实质性差异make_shared<T>().

但是重置共享指针以指向某个新实例的方法呢.以前,我通常会使用reset(new T())会员.但是,这不是因为没有首先使用make_shared()的问题吗?(即它不允许make_shared分配对象,因此它被强制将ref计数放在单独的分配中而不是与T本身相同的分配中?)

是否更好地继续使用:

   mysharedptr = make_shared<T>(args...);
Run Code Online (Sandbox Code Playgroud)

或者,还有更好的方法?

并且不应该像make_shared那样重置提供参数的变量转发,这样就可以编写mysharedptr.reset(args ...);?

c++ shared-ptr c++11

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

shared_ptr &lt;void&gt;如何知道要使用哪个析构函数?

我编写了以下代码,以查看a shared_ptr<void>作为最后引用a shared_ptr<Thing>并被销毁时的行为。

#include <iostream>
#include <string>
#include <memory>

using namespace std;

struct Thing{
    ~Thing(){
        cout<<"Destroyed\n";
    }
    int data;
};

int main(){
    {
        shared_ptr<void> voidPtr;
        {
            shared_ptr<Thing> thingPtr = make_shared<Thing>();
            voidPtr = thingPtr;
        }
        cout<<"thingPtr is dead\n";
    }
    cout<<"voidPtr is dead\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

哪个输出:

thingPtr is dead
Destroyed
voidPtr is dead
Run Code Online (Sandbox Code Playgroud)

它以我喜欢的方式运行,但是这完全是出乎意料的,我想了解这里发生了什么。最初的共享指针不再存在,最后只是一个shared_ptr<void>。因此,我希望这个共享指针的行为就像它持有a void*并且不知道有关Thing::~Thing(),但是它称之为。这是设计使然吧?void共享指针如何做到这一点?

c++ void shared-ptr

34
推荐指数
1
解决办法
1538
查看次数

智能指针如何在删除和删除[]之间进行选择?

考虑:

delete new std :: string [2];
delete [] new std :: string;
Run Code Online (Sandbox Code Playgroud)

每个人都知道第一个是错误.如果第二个不是错误,我们就不需要两个不同的运算符.

现在考虑:

std :: unique_ptr <int> x (new int [2]);
std :: unique_ptr <int> y (new int);
Run Code Online (Sandbox Code Playgroud)

是否x知道使用delete[]而不是 delete


背景:当我认为指针的数组类型限定将是一个方便的语言功能时,这个问题浮现在我脑海中.

int *[] foo = new int [2]; // OK
int *   bar = new int;     // OK
delete [] foo;             // OK
delete bar;                // OK
foo = new int;             // Compile error
bar = new int[2];          // Compile error
delete foo; …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers shared-ptr delete-operator c++11

33
推荐指数
2
解决办法
4745
查看次数

c ++ 11中的intrusive_ptr

C++ 11有相同的东西boost::intrusive_ptr吗?

我的问题是我的C++代码有一个C风格的界面.接口的两端都可以使用C++,但出于兼容性原因需要公开C接口.我无法使用,std::shared_ptr因为我必须通过两个(或更多)智能指针来管理对象.我无法找到类似的解决方案boost::intrusive_ptr.

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

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

boost shared_ptr <XXX>线程安全吗?

我有一个问题boost::shared_ptr<T>.

有很多线程.

using namespace boost;

class CResource
{
  // xxxxxx
}

class CResourceBase
{
public:
   void SetResource(shared_ptr<CResource> res)
   {
     m_Res = res;
   }

   shared_ptr<CResource> GetResource()
   {
      return m_Res;
   }
private:
   shared_ptr<CResource> m_Res;
}

CResourceBase base;

//----------------------------------------------
// Thread_A:
    while (true)
    {
       //...
       shared_ptr<CResource> nowResource = base.GetResource();
       nowResource.doSomeThing();
       //...
    }

// Thread_B:
    shared_ptr<CResource> nowResource;
    base.SetResource(nowResource);
    //...
Run Code Online (Sandbox Code Playgroud)

Q1

如果Thread_A不关心nowResource是最新的,那么这部分代码会有问题吗?

我的意思是当Thread_B没有SetResource()完全,Thread_A得到一个错误的智能点GetResource()

Q2

线程安全是什么意思?

如果我不关心资源是否是最新的,那么shared_ptr<CResource> nowResource当程序nowResource被释放时会崩溃程序还是会破坏问题 …

c++ boost thread-safety shared-ptr boost-smart-ptr

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

为什么std :: weak_ptr :: expired已经优化了?

在下面的代码中,while ( !Ref.expired() );快乐地优化为无限循环.如果代码行更改为while ( !Ref.lock() );.一切都按预期工作.真的有两个问题:

1)当std::weak_ptr::expired()访问内存隔离计数器时,编译器如何优化过期?

2)Ref.lock()实际上是安全的,还是可以将其优化掉?

示例代码如下.

#include <iostream>
#include <memory>
#include <thread>
#include <chrono>

class A
{
public:

    A() 
    { 
        m_SomePtr = std::make_shared<bool>( false );
    }

    virtual ~A()
    {
        std::weak_ptr<bool> Ref = m_SomePtr;
        m_SomePtr.reset();

        // Spin (will be optimised into an infinite loop in release builds)
        while ( !Ref.expired() );
    }

    std::shared_ptr<bool> GetPtr() const { return m_SomePtr; }

private:
    std::shared_ptr<bool> m_SomePtr;
};

class B
{
public:
    B( std::shared_ptr<bool> …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading shared-ptr visual-c++ c++11

32
推荐指数
1
解决办法
780
查看次数

shared_ptr和weak_ptr的琐碎情况失败

我在shared_ptrweak_ptr一起使用时遇到了麻烦enable_shared_from_this

当我用Google搜索所见事物的症状时,每个人都建议“ shared_from_this()当没有shared_ptr实例拥有您的对象时,您将无法使用。

但这不是我的情况。

考虑以下代码:

#include <memory>
#include <cassert>

class MyClass : std::enable_shared_from_this<MyClass>
{
public:
    void this_fails()
    {
        // Doesn't even assert(), because it throws bad_weak_ptr
        assert(shared_from_this());
    }
    void this_fails_too()
    {
        std::weak_ptr<MyClass> weak = weak_from_this();
        std::shared_ptr<MyClass> strong = weak.lock();
        // This assert fails
        assert(strong.get());
    }
};

int main()
{
    std::shared_ptr<MyClass> obj = std::make_shared<MyClass>();

    obj->this_fails();
    obj->this_fails_too();
}

Run Code Online (Sandbox Code Playgroud)

两种方法都会MyClass使程序崩溃。我一定缺少明显的东西-这是什么?

c++ shared-ptr weak-ptr private-inheritance enable-shared-from-this

32
推荐指数
2
解决办法
1435
查看次数

为什么shared_from_this从技术角度来看不能在构造函数中使用?

在第91页的"C++标准库 "一书中,我读过以下内容shared_from_this():

问题是,shared_ptr卖场本身的私有成员 Person的基类enable_shared_from_this<>,在最后的人的建设.

该书的相关代码片段是:

class Person : public std::enable_shared_from_this<Person> {
   ...
};
Run Code Online (Sandbox Code Playgroud)

我不明白这里有两件事:

  1. 这是谁shared_ptr存储自己?
  2. 如何在建筑结束时将自己存放在任何地方Person?我认为构造Person最终是由我编写的构造函数的最后一个语句.

我知道还有weak_ptr尚未初始化的内容.

编辑:感谢Angew!shared_from_this将工作后,才第一次shared_ptrPerson创建.这shared_ptr将检查Person类是否继承enable_shared_from_this,如果是,则初始化其内部weak_ptr.

c++ constructor shared-ptr

31
推荐指数
1
解决办法
8512
查看次数

为什么不赞成使用std :: shared_ptr :: unique()?

这是什么技术问题std::shared_ptr::unique()是它在C++ 17中被弃用的原因?

根据cppreference.com,std::shared_ptr::unique()在C++ 17中被弃用

从C++ 17开始不推荐使用此函数,因为use_count它只是多线程环境中的近似值.

我理解这是真的use_count() > 1:虽然我拿着它的引用,但其他人可能会同时放弃他或创建一个新副本.

但是如果use_count()返回1(这是我在调用时感兴趣的话unique())那么就没有其他线程可以以一种活泼的方式改变这个值,所以我希望这应该是安全的:

if (myPtr && myPtr.unique()) {
    //Modify *myPtr
}
Run Code Online (Sandbox Code Playgroud)

我自己的搜索结果:

我发现这个文件:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0521r0.html建议弃用以回应C++ 17 CD评论CA 14,但我找不到评论本身.

作为替代方案,该文件建议增加一些说明,包括以下内容:

注意:当多个线程可以影响返回值时use_count(),结果应视为近似值.特别是,use_count() == 1并不意味着通过先前破坏的访问shared_ptr在任何意义上都已完成. - 结束说明

我理解这可能use_count()是当前指定方式的情况(由于缺乏保证的同步),但为什么分辨率不仅仅是指定这样的同步并因此使上述模式安全?如果有一个基本的限制,不允许这种同步(或使其成本高昂),那么如何才能正确实现析构函数?

更新:

我忽略了@ alexeykuzmin0和@rubenvb提出的明显案例,因为到目前为止我只unique()shared_ptr其他线程本身无法访问的实例上使用过.因此,没有任何危险,特定的实例将以一种活泼的方式被复制.

我仍然有兴趣了解CA 14究竟是什么,因为我相信unique()只要保证与shared_ptr其他线程上的不同实例发生的任何事情同步,我的所有用例都会起作用.所以它对我来说似乎仍然是一个有用的工具,但我可能会忽略一些基本的东西.

为了说明我的想法,请考虑以下事项:

class MemoryCache {
public:
    MemoryCache(size_t size)
        : …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading shared-ptr c++17

31
推荐指数
2
解决办法
3466
查看次数