tjw*_*992 1 c++ shared-ptr weak-ptr unique-ptr c++11
通常,如果您使用a 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
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,涉及到该如何处理std::unique_ptr?
使用唯一指针可确保当前资源由其std::unique_ptr自身专有。但是,如果我想创建一个指向不拥有该资源的资源的指针,该怎么办?我不能使用a,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
}
Run Code Online (Sandbox Code Playgroud)
我可以想到的创建指向a拥有的对象的非所有者指针的唯一方法std::unique_ptr是使用原始指针,但是从上面的代码可以看出,这可能会导致线程化应用程序出现问题。有没有更好的方法可以实现相同的目标?
Based on your last example, this is a scenario where std::shared_ptr and std::weak_ptr should be used.
std::unique_ptr and a non-owning Raw Pointer should be used in the scenario where you have a guarantee that the smart pointer will outlive the raw pointer.
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++;
}
};
Run Code Online (Sandbox Code Playgroud)
If you can make this guarantee, you should be using std::unique_ptr and a raw pointer to represent this object. This is ideomatically correct.
If, however, you can't guarantee lifetime at the time you need to manipulate the object, then references should be provided by std::weak_ptr, which are used to acquire ownership (even if only temporarily!) to make changes.
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();
}
Run Code Online (Sandbox Code Playgroud)