c++ - 引用你不拥有的 "std::unique_ptr"(使用原始指针?)

标签 c++ c++11 shared-ptr unique-ptr weak-ptr

通常,如果您使用 std::shared_ptr 指向一个对象,并且您想要创建另一个指向该对象但不共享所有权的指针,您将创建一个 std::weak_ptr.

// Create a shared pointer to own the object
std::shared_ptr<int> p = std::make_shared<int>(42);

// Create a weak pointer (that does not own the object)
std::weak_ptr<int> q(p);

// Use the weak pointer some time later
if (std::shared_ptr ptr = q.lock()) {
  // use *ptr
}

我的问题是,当涉及到 std::unique_ptr 时,您如何做到这一点?

使用唯一指针可确保当前资源专为 std::unique_ptr 本身所有。但是,如果我想创建一个指向不拥有该资源的同一资源的指针怎么办?我不能使用 std::weak_ptr,因为弱指针旨在与来自 std::shared_ptr 的引用计数一起使用。我会在这里使用原始指针吗?或者有更好的选择吗?

// Create a unique pointer to own the object
std::unique_ptr<int> p = std::make_unique<int>(42);

// Create a non-owning pointer to the same object
// Is this really the best way?
int* q = p.get();

// Use the pointer some time later
if (q != nullptr) {

  // Imagine this may be multithreaded...
  // what happens if p.reset() is called by another thread while the current thread is RIGHT HERE.

  // use *q
}

我能想到的创建一个指向由 std::unique_ptr 拥有的对象的非拥有指针的唯一方法是使用原始指针,但正如您从上面的代码中看到的这可能会导致线程应用程序出现问题。有没有更好的方法来实现相同的目标?

最佳答案

根据你的最后一个例子,这是一个应该使用 std::shared_ptrstd::weak_ptr 的场景。

std::unique_ptr 和非拥有原始指针应该在您保证智能指针将比原始指针长寿的场景中使用。

class A {
    std::unique_ptr<int> ptr = std::make_unique<int>(5);
public:
    int* get_ptr() const{return ptr.get();}
};

class B {
    A a;
public:
    void do_something() {
        //int * ptr = a.get_ptr();//Valid, but not advised
        int & ref = *a.get_ptr();//Preferred
        ref++;
    }
};

如果你能保证这一点,你应该使用 std::unique_ptr 和一个原始指针来表示这个对象。这在思想上是正确的。

但是,如果在需要操作对象时无法保证生命周期,则应由 std::weak_ptr 提供引用,用于获取所有权(即使只是暂时的!)进行更改。

class A {
    std::shared_ptr<int> ptr = std::make_shared<int>(5);
public:
    std::weak_ptr<int> get_ptr() const {
        return ptr;//Implicitly converts
    }
    void destroy() {
        ptr.reset();
    }
};

class B {
    std::weak_ptr<int> ptr;
public:
    B(std::weak_ptr<int> ptr) : ptr(ptr) {}
    void do_something() {
        if(auto owned_ptr = ptr.lock()) {//owned_ptr will be deduced to be of type std::shared_ptr<int>
            *owned_ptr++; //Guaranteed to only execute if the pointer is still valid
        }
    }
};

int main() {
    A a;
    B b(a.get_ptr());
    if(get_random_value() > 10)
        a.destroy();
    b.do_something();
}

关于c++ - 引用你不拥有的 "std::unique_ptr"(使用原始指针?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55028529/

相关文章:

c++ - 结构模板的默认参数

C++避免检查双指针持有的未初始化值

c++ - std::shared_ptr 的 use_count 有哪些递增方式?

c++ - 如何传递对 std::shared_ptr 管理的指针的引用

c++ - 使用 lambda 进行变体访问的最佳方法

c++ - 访问类内部数据结构的最佳方式是什么?

c++ - 删除模板分配的数组,可能已经分配了索引

c++ - 比较任意类型的整数

c++ - 从 map 中检索后 map 中的对象损坏

C++设计: Passing pointer/reference to ref-counted object