Mis*_*ter 4 c++ smart-pointers resource-management shared-ptr unique-ptr
假设我有一个管理器类,其中包含某个对象的向量:
class SomeObjectManager
{
private:
std::vector<SomeObject> _heldObjects;
};
Run Code Online (Sandbox Code Playgroud)
在那个类中,我有一些函数可以遍历所述向量以返回请求的对象。
SomeObject getSomeObjectByName(std::string nameToFind);
Run Code Online (Sandbox Code Playgroud)
我需要知道的是什么时候使用智能指针是合适的。我真的应该返回如下内容吗?
std::shared_ptr<SomeObject> getSomeObjectByName(std::string nameToFind);
Run Code Online (Sandbox Code Playgroud)
或者我应该使用诸如 unique_ptr 或 weak_ptr 之类的其他东西吗?我希望 SomeObjectManager 类拥有返回的实际对象,并且永远不会说 SomeObject 被删除,除非 Manager 这样做。
我在 C# 模式下工作了一段时间后,最近才回到 C++ 世界;感谢您的帮助并消除我的困惑。
我已经阅读了很多关于这件事的书,但从未真正找到针对我的特定情况的直接答案。
编辑 #1
我想用这个改写我的最后几句话:
我希望 SomeObjectManager 类拥有返回的实际对象,并且从未说过 SomeObject 从向量中删除并随后被删除,超出范围,直到 Manager 强制它这样做。例如:
void SomeObjectManager::removeSomeObjectByName(const std::string& objectToRemove);
Run Code Online (Sandbox Code Playgroud)
这只会迭代向量,找到 said SomeObject,然后从向量中删除它。
既然SomeObjectManager是老板的的SomeObject实例(存储在它的std::vector数据成员),我只是回到原始指针,因为他们实际上是观察指针。
std::vector<SomeObject> _heldObjects;
SomeObject* getSomeObjectByName(const std::string& nameToFind) {
... find index of object corresponding to 'nameToFind'
return &_heldObjects[foundIndex];
}
Run Code Online (Sandbox Code Playgroud)
(请注意,我nameToFind使用了对 的引用const,因为我假设这nameToFind是一个输入字符串,因此如果在方法内部您只是观察该字符串,则可以避免使用 进行深层复制const &)。
当你拥有原始指针时你必须注意(它们应该被包裹在安全的 RAII 边界内),但观察原始指针是好的。
只需确保 的生命周期SomeObjectManager超过其客户端的生命周期,以确保客户端正在引用有效的对象。
另请注意,如果向向量数据成员添加新项(例如使用std::vector::push_back()),则存储在向量中的先前实例的地址SomeObject可能会更改。所以,如果你给外面的人指点,他们就无效了。
因此,在将指向其元素的指针指向外部的客户端代码之前,请确保矢量大小和矢量内容未更改。
另一种方法是将其std::vector<std::unique_ptr<SomeObject>>作为数据成员。在这种情况下,即使调整了向量的大小,您使用智能指针(特别是使用std::unique_ptr::get())返回的地址仍然有效:
std::vector<std::unique_ptr<SomeObject>> _heldObjects;
SomeObject* getSomeObjectByName(const std::string& nameToFind) {
... find index of object corresponding to 'nameToFind'
return _heldObjects[foundIndex].get();
}
Run Code Online (Sandbox Code Playgroud)
PS
另一种选择可能返回引用到const SomeObject(假设这使用的const品牌在你的设计感):
std::vector<SomeObject> _heldObjects;
const SomeObject& getSomeObjectByName(const std::string& nameToFind) const {
... find index of object corresponding to 'nameToFind'
return _heldObjects[foundIndex];
}
Run Code Online (Sandbox Code Playgroud)