指代您不拥有的“ std :: unique_ptr”(使用原始指针?)

时间:2019-03-06 17:04:16

标签: 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所拥有对象的非所有者指针的唯一方法是使用原始指针,但是正如您从上面的代码中可以看到的那样,这可能会导致线程问题应用程序。有没有更好的方法可以实现相同的目标?

2 个答案:

答案 0 :(得分:5)

这取决于额外的指针是否会超过unique_ptr

  • 如果非所有者指针绝对不能生存,则unique_ptr:将其设为普通指针。谁得到这种指针都可以认为它是有效的,但是不能假定拥有它所指向的内存。
  • 如果非所有者指针可能过期,则unique_ptr:您的原始指针不是真的“唯一”;并且您应该将unique_ptr替换为shared_ptr,并通过weak_ptr作为非所有者副本。

我刚刚注意到,这个答案基本上是Xirema's answer的简短摘要。请投票/接受该答案!

答案 1 :(得分:3)

根据您的上一个示例,在这种情况下,应使用// myContainer.js import React, { Component } from 'react' import MyChild from 'some/path/myChild' class MyContainer extends Component { state = { name: 'foo' } handleNameChange = name => { this.setState({ name }) } render() { return ( <MyChild name={this.state.name} onNameChange={this.handleNameChange} /> ) } } export default MyContainer // myChild.js import React, { Component } from 'react' class MyChild extends Component { handleInputChange = event => { this.props.onNameChange(event.target.value) } render() { return ( <div> <input type="text" onChange={this.handleInputChange} value={this.props.name} /> <div>The name is: {this.props.name}</div> </div> ) } } export default MyChild std::shared_ptr

std::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