如何在现代C++中表达关系而不表达所有权

How to express in Modern C++ the referes-to relationship without expressing ownership?

本文关键字:关系 所有权 C++      更新时间:2023-10-16

从"不应该使用原始指针"这个成语的角度出发,我研究了智能指针,以找出哪一个最适合引用关系。

所指的关系,我的意思与此代码相同:

class A
{
public:
    A(B & b) : 
        m_refB( b ) 
    {   }
private:
    B & m_refB;    // A refers to B
};

但是,如果没有使用引用的所有缺点(以后不能绑定,不能重新分配,A不能再是默认的可构造等)。

然而,每个智能指针在其自身的语义中都在表达一个所有权概念。它们甚至是围绕着这个所有权概念命名的(当所有权仅对一个对象唯一时为唯一指针,当所有权在多个对象之间共享时为共享指针等)。

我想表明,A指的是B,但A并不拥有B。std::reference_wrapper< B >能胜任这项工作吗?或者这是一个错误的用法?

没有"不应该使用原始指针"这回事。"不应使用拥有原始指针"。使用一个原始指针来引用这个成语并没有错。智能指针在这方面做得太过火了。特别是std::weak_ptr:)

这就是std::weak_ptr的作用。它表达了它指的是某个东西,但它并不拥有它,而且这个东西可能在指它的对象消失之前就消失了。

如果您决定需要引用的对象,则可以使用lock(),它将向对象返回shared_ptr并延长其生存期,直到shared_ptr超出范围。

我认为@SergeyA提供的答案很棒,我自己也投了赞成票。

然而,如果您真的不想在代码中看到原始指针,那么您总是可以创建一个包装类,用于传达所需的语义。

例如:

/**
 * A class that refers to an existing object instance. This class does not own
 * the existing object instance and the lifetime of the existing object instance
 * must be greater than the lifetime of instantiations of this class.
 */
template<typename T>
class Handle
{
public:
    Handle(T& object) : mObject(&object) {}
    // ... other functions necessary to use this object ...
private:
    T* mObject;
};