There's two containers: owner and non-owner of resource. As I have only 1 owner, I suppose I need 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;
};
What of kind of pointer i have to use for non-owner container? First thought was raw pointer. But i cannot give guarantee that lifetime of Obj match or exceed lifetime of Non-owner container.
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
}
I could use shared_ptr for owner and weak_ptr for non-owner, so I could check if weak_ptr is expired or not. But shared_ptr means that i have shared ownership, that's not true in my case, and I no need reference counter.
EDIT:
I'm not trying to extend lifetime. When owner container is destroyed, I want to avoid dangling pointers. As I wrote above, I could use 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
}
But in this case, I pay for reference counter, and it is philosophically wrong: with only one owner use shared_ptr.