【问题标题】:Creating shared_ptr from raw pointer从原始指针创建 shared_ptr
【发布时间】:2011-01-12 04:11:37
【问题描述】:

我有一个指向对象的指针。我想将它存储在两个都有所有权的容器中。因此,我认为将其设为 C++0x 的 shared_ptr 会很好。如何将原始指针转换为 shared_pointer?

typedef unordered_map<string, shared_ptr<classA>>MAP1;
MAP1 map1;
classA* obj = new classA();
map1[ID] = how could I store obj in map1??

谢谢

【问题讨论】:

    标签: c++


    【解决方案1】:

    您需要确保不要使用相同的原始指针初始化两个 shared_ptr 对象,否则它将被删除两次。一种更好(但仍然很糟糕)的方法:

    classA* raw_ptr = new classA;
    shared_ptr<classA> my_ptr(raw_ptr);
    
    // or shared_ptr<classA> my_ptr = raw_ptr;
    
    // ...
    
    shared_ptr<classA> other_ptr(my_ptr);
    // or shared_ptr<classA> other_ptr = my_ptr;
    // WRONG: shared_ptr<classA> other_ptr(raw_ptr);
    // ALSO WRONG: shared_ptr<classA> other_ptr = raw_ptr;
    

    警告:上面的代码显示了不好的做法! raw_ptr 根本不应该作为变量存在。如果您使用new 的结果直接初始化您的智能指针,您可以降低意外初始化其他智能指针不正确的风险。你应该做的是:

    shared_ptr<classA> my_ptr(new classA);
    
    shared_ptr<classA> other_ptr(my_ptr);
    

    好在代码也更简洁了。

    编辑

    我可能应该详细说明它如何与地图一起使用。如果你有一个原始指针和两个地图,你可以做一些类似于我上面展示的事情。

    unordered_map<string, shared_ptr<classA> > my_map;
    unordered_map<string, shared_ptr<classA> > that_guys_map;
    
    shared_ptr<classA> my_ptr(new classA);
    
    my_map.insert(make_pair("oi", my_ptr));
    that_guys_map.insert(make_pair("oi", my_ptr));
    // or my_map["oi"].reset(my_ptr);
    // or my_map["oi"] = my_ptr;
    // so many choices!
    

    【讨论】:

    • 不要在变量中暴露原始指针。通过这样做,您给维护者一个更容易搞砸并将 RAW 指针放入另一个共享指针的机会。只需使用my_ptr(new ClassA()); 这样维护人员就必须做额外的工作才能搞砸。
    • @Martin York 我只是在编辑以包含关于此的一点;我将添加一个更明确的注释。但你是对的。 :)
    • // or shared_ptr&lt;classA&gt; my_ptr = raw_ptr;std::shared_ptr 中是错误的,因为它应该明确为// or shared_ptr&lt;classA&gt; my_ptr(raw_ptr);
    • 其实最好的做法是make_shared,完全避免new。我不记得深层原因,如果新投掷,我认为这是在 Sean Parent 的演讲中。
    【解决方案2】:

    您可以使用多种方式,但 reset() 会很好:

    map1[ID].reset(obj);
    

    为了解决让两个地图引用同一个 shared_ptr 的问题,我们可以:

    map2[ID] = map1[ID];
    

    请注意,避免双重删除的技巧通常是尽量避免使用原始指针。 因此避免:

    classA* obj = new classA();
    map1[ID].reset(obj);
    

    而是将新堆对象直接放入 shared_ptr。

    【讨论】:

    • 这本身并不是一个坏习惯,它是 c-practice!
    猜你喜欢
    • 2019-09-29
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    • 2021-11-15
    • 2013-10-09
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    相关资源
    最近更新 更多