[英]Shared Pointer to an object in a vector
我试图弄清楚,如果您创建一个共享指针,该指针指向一个保存在向量中的 object,会发生什么。
代码如下所示:
class TestObject
{
public:
int someTestData;
};
class Test
{
public:
std::shared_ptr<TestObject> testPointer;
std::shared_ptr<std::vector<TestObject>> getTestVector()
{
return testVector;
}
private:
std::shared_ptr<std::vector<TestObject>> testVector;
};
问题是,我既想支持对所有 TestObjects 的快速迭代,又想提供指向向量中单个对象的共享指针。 但是现在我不知道如果向量中 object 的最后一个共享 ptr 被删除会发生什么。
编辑:
为了澄清,我需要什么:
我需要一个 MemoryManager Class,它有一个 CreateTestObject 方法,它创建一个新的 TestObject,将它存储在一个向量或其他支持快速迭代的容器中,并将某种 shared_ptr 返回到新创建的 object 以便 ZA8CFDE6331BD59EB2AC96F968新的 TestObject 有一个参考。
现在,当最后一个 shared_ptr 超出 scope 时,我还需要 TestObject 的 shared_ptr 以便能够从它存储的容器中删除 TestObject,这样我就不会留下一个充满未使用 TestObjects 的向量。
很难知道最终会发生什么,因为您没有共享实际初始化testPointer
的代码。 但是您正在寻找的是别名std::shared_ptr
:
testPointer = {testVector, &(*testVector)[0]};
从那时起, testPointer
指向向量的第一个元素,但与testVector
共享向量本身的所有权,从而提供正确的语义。
请注意,如果您导致向量重新分配,这不会阻止向量重新定位其存储并使testPointer
悬空。
作为记录,尝试构造一个拥有元素本身的std::shared_ptr
,如下所示:
testPointer.reset(&(*testVector)[0]); // Wrong!
...必然会触发 UB,因为std::vector
已经对其元素拥有唯一的所有权,并且您无法让std::vector
或std::shared_ptr
放弃所有权。
“我试图弄清楚,如果你创建一个共享指针,它指向一个保存在向量中的 object,会发生什么。”
这是一个非常糟糕的主意,因为向量的任何元素的 position 都可以通过向向量中添加或删除元素来改变。 您实施的只是所有权的重复,这会破坏基本的 OOP 概念。
object 是否从向量中删除?
共享指针是 object 的“所有者”,向量也是所有者。 所以它是概念性的破坏!
这会导致未定义的行为吗?
它仍然是未定义的,因为你会生成悬空点,因为 vector 可以移动它的对象。
如果这不起作用,我该如何实现我想要的行为?
您已经可以通过operator[]
快速访问,并且您已经有了“指针”,因为迭代器可以用作任何其他指针。
您可以使用带有shared_ptr
的自定义删除器并使用诸如boost::stable_vector
类的容器来执行此操作:
testVector.emplace_back();
auto it = V.end()-1;
auto deleter = [&testVector, it] (int*) {testVector.erase(it);};
std::shared_ptr<TestObject> ptr(&testVector.back(), deleter);
当 object 的最后一个shared_ptr
超出 scope 时,它将从TestVector
中删除。 但是请注意,这反过来不起作用:如果TestVector
通过任何其他方式(例如通过TestVector
超出范围)从 TestVector 中删除,这将触发未定义的行为,因此您有责任确保这不会发生。 另请注意,这不适用于std::vector
,因为在调整向量大小时迭代器会失效。 但是,您可以使用std::list
,尽管这可能会比stable_vector
慢。
这不是最干净的解决方案(因为如果你不小心,很可能会触发 UB),但是这样做会更复杂。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.