2017-04-23 24 views
0

有两个容器:资源的所有者和非所有者。由于我只有1个拥有者,我想我需要unique_ptr。std :: 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的生命周期匹配或超过非所有者容器的寿命。

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。

+0

对普通的'std :: vector '有什么争议?你在做什么主要看起来很危险。本质上你试图延长生命,这意味着你的所有权是错误的。 – stefan

+0

我使用继承和多态,Obj是一个基类。 –

+1

如果拥有的容器应该是唯一的拥有者,那么对这些对象的所有访问都必须经过它。 – StoryTeller

回答

2

你居然有共同的所有权:当你通过NonOwningContainer -contained指针性的东西访问对象,你必须采取所有权,或者当你使用它的对象可以从你下了消失。

因为你不能保证该对象将不会从你下了消失:

但我不能给保证obj是否匹配的使用寿命或超过非业主容器的寿命。

那么你唯一的选择就是分享所有权。因此shared_ptrweak_ptr是合适的方法。

此外,根据OwnershipContainerNonOwnershipContainer的使用寿命的不同,请注意the interaction between std::make_shared and std::weak_ptr