std::unique_ptr 的非所有权副本
Non-ownership copies of std::unique_ptr
有两个容器:资源的所有者和非所有者。因为我只有 1 个所有者,所以我想我需要 unique_ptr.
class OwnershipContainer {
public:
void add(std::unique_ptr<Obj> obj) {
objects.push_back(std::move(obj));
}
Obj* get(std::size_t i) { return objects[i].get(); }
private:
std::vector<std::unique_ptr<Obj>> objects;
};
非所有者容器必须使用哪种指针?首先想到的是原始指针。但我不能保证 Obj 的生命周期匹配或超过 Non-owner 容器的生命周期。
class NonOwnershipContainer {
public:
void add(Obj *obj) {
objects.push_back(obj);
}
Obj* get(std::size_t i) { return objects[i]; }
private:
std::vector<Obj*> objects;
};
int main() {
NonOwnershipContainer nonOwnershipContainer;
{
OwnershipContainer ownershipContainer;
ownershipContainer.add(std::make_unique<Obj>(1));
nonOwnershipContainer.add(ownershipContainer.get(0));
}
auto pobj = nonOwnershipContainer.get(0); // dangling pointer
}
我可以对所有者使用 shared_ptr,对非所有者使用 weak_ptr,这样我就可以检查 weak_ptr 是否过期。但是 shared_ptr 意味着我有共享所有权,这对我来说不是真的,我不需要参考计数器。
编辑:
我不是想延长寿命。当所有者容器被销毁时,我想避免悬挂指针。正如我上面写的,我可以使用 shared_ptr + weak_ptr.
class OwnershipContainer {
public:
void add(std::shared_ptr<Obj> obj) {
objects.push_back(obj);
}
std::shared_ptr<Obj> get(std::size_t i) { return objects[i]; }
private:
std::vector<std::shared_ptr<Obj>> objects;
};
class NonOwnershipContainer {
public:
void add(std::shared_ptr<Obj> obj) {
objects.push_back(obj);
}
std::shared_ptr<Obj> get(std::size_t i) { return objects[i].lock(); }
private:
std::vector<std::weak_ptr<Obj>> objects;
};
int main() {
NonOwnershipContainer nonOwnershipContainer;
{
OwnershipContainer ownershipContainer;
ownershipContainer.add(std::make_shared<Obj>(1));
nonOwnershipContainer.add(ownershipContainer.get(0));
}
auto pobj = nonOwnershipContainer.get(0); // no more dangling pointer, pobj == nullptr
}
但在这种情况下,我为参考计数器付费,这在哲学上是错误的:只有一个所有者使用 shared_ptr。
你实际上确实拥有共享所有权:当你通过NonOwningContainer
包含的类似指针的东西访问对象时,你必须取得所有权,否则对象可能在您使用它时从您身下消失。
因为你不能保证物体不会从你身下消失:
But i cannot give guarantee that lifetime of Obj match or exceed lifetime of Non-owner container.
那么您唯一的选择就是共享所有权。因此 shared_ptr
和 weak_ptr
是合适的方法。
此外,根据 OwnershipContainer
和 NonOwnershipContainer
的生命周期差异,请注意 the interaction between std::make_shared
and std::weak_ptr
。
有两个容器:资源的所有者和非所有者。因为我只有 1 个所有者,所以我想我需要 unique_ptr.
class OwnershipContainer {
public:
void add(std::unique_ptr<Obj> obj) {
objects.push_back(std::move(obj));
}
Obj* get(std::size_t i) { return objects[i].get(); }
private:
std::vector<std::unique_ptr<Obj>> objects;
};
非所有者容器必须使用哪种指针?首先想到的是原始指针。但我不能保证 Obj 的生命周期匹配或超过 Non-owner 容器的生命周期。
class NonOwnershipContainer {
public:
void add(Obj *obj) {
objects.push_back(obj);
}
Obj* get(std::size_t i) { return objects[i]; }
private:
std::vector<Obj*> objects;
};
int main() {
NonOwnershipContainer nonOwnershipContainer;
{
OwnershipContainer ownershipContainer;
ownershipContainer.add(std::make_unique<Obj>(1));
nonOwnershipContainer.add(ownershipContainer.get(0));
}
auto pobj = nonOwnershipContainer.get(0); // dangling pointer
}
我可以对所有者使用 shared_ptr,对非所有者使用 weak_ptr,这样我就可以检查 weak_ptr 是否过期。但是 shared_ptr 意味着我有共享所有权,这对我来说不是真的,我不需要参考计数器。
编辑:
我不是想延长寿命。当所有者容器被销毁时,我想避免悬挂指针。正如我上面写的,我可以使用 shared_ptr + weak_ptr.
class OwnershipContainer {
public:
void add(std::shared_ptr<Obj> obj) {
objects.push_back(obj);
}
std::shared_ptr<Obj> get(std::size_t i) { return objects[i]; }
private:
std::vector<std::shared_ptr<Obj>> objects;
};
class NonOwnershipContainer {
public:
void add(std::shared_ptr<Obj> obj) {
objects.push_back(obj);
}
std::shared_ptr<Obj> get(std::size_t i) { return objects[i].lock(); }
private:
std::vector<std::weak_ptr<Obj>> objects;
};
int main() {
NonOwnershipContainer nonOwnershipContainer;
{
OwnershipContainer ownershipContainer;
ownershipContainer.add(std::make_shared<Obj>(1));
nonOwnershipContainer.add(ownershipContainer.get(0));
}
auto pobj = nonOwnershipContainer.get(0); // no more dangling pointer, pobj == nullptr
}
但在这种情况下,我为参考计数器付费,这在哲学上是错误的:只有一个所有者使用 shared_ptr。
你实际上确实拥有共享所有权:当你通过NonOwningContainer
包含的类似指针的东西访问对象时,你必须取得所有权,否则对象可能在您使用它时从您身下消失。
因为你不能保证物体不会从你身下消失:
But i cannot give guarantee that lifetime of Obj match or exceed lifetime of Non-owner container.
那么您唯一的选择就是共享所有权。因此 shared_ptr
和 weak_ptr
是合适的方法。
此外,根据 OwnershipContainer
和 NonOwnershipContainer
的生命周期差异,请注意 the interaction between std::make_shared
and std::weak_ptr
。