繁体   English   中英

指向向量中 object 的共享指针

[英]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 被删除会发生什么。

  • object 是否从向量中删除?
  • 这会导致未定义的行为吗?
  • 如果这不起作用,我该如何归档我想要的行为?

编辑:

为了澄清,我需要什么:

我需要一个 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::vectorstd::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM