C++ 指向向量中对象的共享指针
我想弄清楚,如果你创建一个共享指针,指向一个向量中的对象,会发生什么 代码如下所示:C++ 指向向量中对象的共享指针,c++,vector,shared-ptr,C++,Vector,Shared Ptr,我想弄清楚,如果你创建一个共享指针,指向一个向量中的对象,会发生什么 代码如下所示: class TestObject { public: int someTestData; }; class Test { public: std::shared_ptr<TestObject> testPointer; std::shared_ptr<std::vector<TestObject>> getTestVector() {
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;
};
类TestObject
{
公众:
int-someTestData;
};
课堂测试
{
公众:
std::共享的测试指针;
std::shared_ptr getTestVector()
{
返回测试向量;
}
私人:
std::共享的测试向量;
};
问题是,我既要支持对所有测试对象的快速迭代,又要提供指向向量中单个对象的共享指针。
但是现在我不知道如果向量中某个对象的最后一个共享ptr被删除会发生什么
- 对象是否从向量中移除李>
- 这会导致未定义的行为吗
- 如果这不起作用,我该如何记录我想要的行为
现在我还需要TestObject的共享ptr,以便在最后一个共享ptr超出范围时,能够从存储在其中的容器中删除TestObject,这样我就不会留下一个充满未使用TestObject的向量。很难知道在您的端会发生什么,因为您没有共享实际初始化
testPointer
的代码。但您要查找的是一个别名std::shared\u ptr
:
testPointer = {testVector, &(*testVector)[0]};
从那时起,testPointer
指向向量的第一个元素,但与testVector
共享向量本身的所有权,从而提供正确的语义
请注意,这不会阻止向量重新定位其存储,并使testPointer
在您导致其重新分配时处于悬挂状态
对于记录,尝试构造一个拥有元素本身的std::shared_ptr
,如下所示:
testPointer.reset(&(*testVector)[0]); // Wrong!
。。。将必然触发UB,因为std::vector
已经拥有其元素的唯一所有权,并且您无法使std::vector
或std::shared\u ptr
放弃所有权。“我试图弄清楚,如果创建一个共享指针,指向向量中的对象,会发生什么。”
这是一个非常糟糕的想法,因为向量中任何元素的位置都可以通过简单地向向量中添加或删除元素来改变。您实现的只是所有权的复制,它阻止了基本的OOP概念
对象是否从向量中移除
共享指针是对象的“所有者”,向量也是所有者。因此,它在概念上是不正确的
这会导致未定义的行为吗
由于向量可以移动其对象,所以在生成悬挂点时,它仍然未定义
如果这不起作用,我如何实现我想要的行为
您已经可以通过
操作符[]
进行快速访问,并且已经有了“指针”,因为迭代器可以用作任何其他指针。您可以使用自定义删除器和共享的\u ptr
并使用类似于boost::stable\u 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);
testVector.emplace_back();
自动it=V.end()-1;
自动删除器=[&testVector,it](int*){testVector.erase(it);};
std::shared_ptr ptr(&testVector.back(),deleter);
当对象的最后一个共享\u ptr
超出范围时,它会将其从TestVector
中删除。但是,请注意,这不会反过来起作用:如果通过任何其他方式(例如通过TestVector
超出范围)将对象从TestVector中删除,这将触发未定义的行为,因此您有责任确保不会发生这种情况。还请注意,这不适用于std::vector
,因为在调整向量大小时迭代器将失效。但是,您可以使用std::list
,尽管这可能比stable\u vector
慢>
这不是最干净的解决方案(因为如果你不小心,很有可能触发UB),但这样做可能要复杂得多。您是否遗漏了部分代码?因为您的问题对我来说并不完全清楚,请尝试澄清您实际需要什么。iirc共享指针所指向的是什么,当指针的生存期到期时,向量中的什么对象真的不会被销毁吗?(然后当向量的生存期到期时,它将销毁已经销毁的对象ub)您是如何从std::vector
的对象中获得shared\ptr
的?testVector
中的对象属于该std::vector
的所有。如果您创建的shared\u ptr
带有这些地址,您几乎肯定只会导致未定义的行为。@mark我在中创建对象向量,然后得到地址,并创建一个共享的ptr,有没有办法归档我想要的行为呢?