如何在现代 C++ 中表达引用关系而不表达所有权?
How to express in Modern C++ the referes-to relationship without expressing ownership?
从"one should not use raw pointers"惯用语的角度出发,我正在研究智能指针以找到最适合指称关系的指针。
指代关系,我的意思和这段代码一样:
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
的用途。它表示它引用了某物但它并不拥有它,并且该事物可能会在引用它的对象消失之前消失。
如果您决定需要引用的对象,您可以对该对象使用 lock()
which will return a shared_ptr 并延长它的生命周期,直到 shared_ptr
超出范围。
没有'one should not use raw pointers'这样的东西。即'one should not use owning raw pointers'。为 refers-to 习语使用原始指针并没有错。智能指针对此来说只是一种矫枉过正。特别是 std::weak_ptr
:)
我觉得 provided by @SergeyA 很棒,我自己投了票。
但是,如果您真的不想在代码中看到原始指针,那么您始终可以创建一个包装器 class 用于传达所需的语义。
例如:
/**
* 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;
};
从"one should not use raw pointers"惯用语的角度出发,我正在研究智能指针以找到最适合指称关系的指针。
指代关系,我的意思和这段代码一样:
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
的用途。它表示它引用了某物但它并不拥有它,并且该事物可能会在引用它的对象消失之前消失。
如果您决定需要引用的对象,您可以对该对象使用 lock()
which will return a shared_ptr 并延长它的生命周期,直到 shared_ptr
超出范围。
没有'one should not use raw pointers'这样的东西。即'one should not use owning raw pointers'。为 refers-to 习语使用原始指针并没有错。智能指针对此来说只是一种矫枉过正。特别是 std::weak_ptr
:)
我觉得
但是,如果您真的不想在代码中看到原始指针,那么您始终可以创建一个包装器 class 用于传达所需的语义。
例如:
/**
* 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;
};