引用一个你不拥有的 "std::unique_ptr"(使用原始指针?)
Referring to a "std::unique_ptr" that you don't own (use a raw pointer?)
通常,如果您使用 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_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
应该提供引用,用于获取所有权(即使只是暂时的!)进行更改。
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();
}
这取决于额外的指针是否可以比 unique_ptr
。
- 如果非拥有指针绝对不能超过
unique_ptr
:使它成为普通指针。得到这种指针的人可以认为它是有效的,但不能假定拥有它指向的内存。
- 如果非拥有指针 可能比
unique_ptr
长寿:您的原始指针并不是真正的 "unique";并且您应该将 unique_ptr
替换为 shared_ptr
并传递 weak_ptr
作为非拥有副本。
刚刚注意到这个回答基本上是对的简单总结。请upvote/accept回答!
通常,如果您使用 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_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
应该提供引用,用于获取所有权(即使只是暂时的!)进行更改。
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();
}
这取决于额外的指针是否可以比 unique_ptr
。
- 如果非拥有指针绝对不能超过
unique_ptr
:使它成为普通指针。得到这种指针的人可以认为它是有效的,但不能假定拥有它指向的内存。 - 如果非拥有指针 可能比
unique_ptr
长寿:您的原始指针并不是真正的 "unique";并且您应该将unique_ptr
替换为shared_ptr
并传递weak_ptr
作为非拥有副本。
刚刚注意到这个回答基本上是对