在C++ 11中,可以使用shared_ptr<>与对象或变量建立所有权关系,并使用weak_ptr<>以非所有权方式安全地引用该对象。

您还可以使用unique_ptr<>与对象或变量建立所有权关系。但是,如果其他非拥有对象也要引用该对象怎么办? weak_ptr<>在这种情况下没有帮助。原始指针很有帮助,但会带来各种不利影响(例如,它们可能是automatically initialized to nullptr,但这是通过与std::*_ptr<>类型不一致的技术来实现的)。

对于通过weak_ptr<>拥有的对象的非所有者引用,相当于unique_ptr<>吗?

这是一个澄清的示例,类似于我正在开发的游戏中的某些内容。

class World
{
public:

    Trebuchet* trebuchet() const { return m_trebuchet.get(); }

private:
    std::unique_ptr< Trebuchet > m_trebuchet;
};

class Victim
{
public:
    Victim( Trebuchet* theTrebuchet ) : m_trebuchet( theTrebuchet ) {}

    ~Victim()
    {
        delete m_trebuchet;     // Duh. Oops. Dumb error. Nice if the compiler helped prevent this.
    }

private:

    Trebuchet* m_trebuchet;    // Non-owning.
};

shared_ptr< Victim > createVictim( World& world )
{
    return make_shared< Victim >( world.trebuchet() );
}

在这里,我们使用原始指针来维护与其他位置通过unique_ptr<>拥有的对象的非所有者关系。但是我们能做的最好的是原始的吗?

希望是一种指针:
  • 看起来像其他现代指针类型。例如。 std::raw_ptr<T>
  • 替换原始指针,以便整个使用现代指针类型的代码库可以通过搜索_ptr<(大致)找到所有指针。
  • 自动初始化为nullptr。

  • 从而:
    int* p;                  // Unknown value.
    std::raw_ptr< int > p;   // null.
    

    这种类型现在已经在C++中存在了吗?是为将来提出的?还是在例如促进?

    最佳答案

    shared_ptr的“通知”行为要求对引用计数控制块进行引用计数。 shared_ptr的引用计数控制块为此使用了单独的引用计数。 weak_ptr实例维护对此块的引用,而weak_ptr本身可以防止对引用计数控制块进行delete ed。当强计数变为零时,指向对象的析构函数将被调用(这可能会或可能不会导致存储该对象的内存的delete ion),并且仅当弱引用计数变为零时,控制块才会被delete ed归零。
    unique_ptr的宗旨是在普通指针上的开销为零。分配和维护引用计数控制块(以支持weak_ptr -ish语义)打破了这一宗旨。如果您需要该描述的行为,那么即使没有对该对象的其他引用,也确实需要共享语义。在这种情况下,仍然需要进行共享-共享对象是否已销毁的状态。

    如果您需要通用的非所有者引用并且不需要通知,请使用普通指针或unique_ptr中对该项目的普通引用。

    编辑:

    在您的示例中,看起来Victim应该请求Trebuchet&而不是Trebuchet*。然后很明显,谁拥有相关对象。

    class World
    {
    public:
    
        Trebuchet& trebuchet() const { return *m_trebuchet.get(); }
    
    private:
        std::unique_ptr< Trebuchet > m_trebuchet;
    };
    
    class Victim
    {
    public:
        Victim( Trebuchet& theTrebuchet ) : m_trebuchet( theTrebuchet ) {}
    
        ~Victim()
        {
            delete m_trebuchet;     // Compiler error. :)
        }
    
    private:
    
        Trebuchet& m_trebuchet;    // Non-owning.
    };
    
    shared_ptr< Victim > createVictim( World& world )
    {
        return make_shared< Victim >( world.trebuchet() );
    }
    

    关于c++ - shared_ptr <>指向weak_ptr <>,就像unique_ptr <>指向…是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17536731/

    10-11 22:33
    查看更多