好吧,我不知道是否有可能,但事情就是:
struct stPiece
{
/* some stuff */
stPiece *mother; // pointer to the piece that created this one
};
vector<stPiece> pieces;
是否可以将“母亲”引用的作品从片段中删除,仅将该指针作为参考?怎么样?
是否会混淆其他参考文献? (即如果它不是向量中的最后一个元素,则通过将下一个元素移动到其他存储位置,而另一个'*母亲'保持不变)。当然,我假设所有子片段都将被删除(因此我不需要更新任何指向同一母亲的指针)。
谢谢!
答案 0 :(得分:2)
如果您的mother
指针直接指向pieces
向量的元素,您将遇到各种麻烦。
从pieces
删除元素会将元素的所有位置移位到更高的索引。即使插入元素也会使所有指针无效,因为向量可能需要重新分配它的内部数组,这可能会将所有元素转移到内存中的新位置。
回答你的主要问题:你不能直接删除指针所在的元素,首先需要通过向量搜索来找到它,或者在向量中计算它的索引。
不将指针存储到pieces
作为mother
,而是元素的索引会使其更加健壮,因此至少插入新元素不会破坏现有的mother
秒。但是从pieces
删除仍会将元素转移到新索引。
对pieces
使用std::list
并将迭代器存储为mother
可能是一种解决方案。如果删除/添加该列表中的其他元素,则std::list
的迭代器不会失效。如果不同的元素可以具有相同的mother
,那么在查找何时删除mother
元素时仍然存在问题,那么使用boost::shared_ptr
可能会更简单。
答案 1 :(得分:2)
目前尚不清楚整个数据结构是如何组织的以及结果会是什么,但是通过指向该元素和向量本身来完全可以从向量中删除元素。您只需要首先将指针转换为迭代器。例如,有一个向量
vector<stPiece> pieces;
和指向该向量的指针
stPiece *mother;
您可以将指针转换为索引
vector<stPiece>::size_type i = mother - &pieces[0];
assert(i < pieces.size());
然后将索引转换为迭代器
vector<stPiece>::iterator it = pieces.begin() + i;
然后删除元素
pieces.erase(it);
就是这样。
但是,在您的数据结构中,您可能会有多个长寿命指针指向同一个向量。任何从这种向量中擦除元素的尝试都会立即使所有这些指针无效。如果你仔细地做所有事情,理论上可以“恢复”它们的有效性,但这将是一个主要的PITA。
我不确定我明白你的意思是“假设所有儿童作品都将被删除”。
答案 2 :(得分:1)
是的,您可以删除母亲引用的作品。
如果删除“母亲”引用的作品,其所有孩子中的母指针将变为悬空,你必须要处理这个问题。< / p>
关于向量中元素的移位,你不需要这样做,它由向量类处理。
答案 3 :(得分:1)
简答:不。
这些碎片按值存储在矢量中。因此,向量迭代器是指向一块的指针。这意味着,指向母件的指针与母亲的矢量迭代器相同。插入(所有迭代器)和擦除(所有迭代器都超过擦除的迭代器)后,矢量迭代器无效,这意味着内存位置将发生变化,几乎不可能保持更新所有指针。
您可以在向量中存储动态分配的部分,即:
vector<stPiece*> pieces
随着向量/从向量中添加/移除片段,母指针不会改变。缺点是:
后两点在您的申请中可能重要,也可能不重要。
答案 4 :(得分:1)
您编码的是单链树。您可能不希望对象包含所有stPiece
,因为这会妨碍实现创建和删除语义。
我猜你想在所有孩子都离开之后删除mother
。
set< stPiece * > all_pieces;
struct stPiece {
boost::shared_ptr< stPiece > const mother;
stPiece( boost::shared_ptr< stPiece > &in_mother )
: mother( in_mother ) {
all_pieces.insert( this );
}
~stPiece() {
all_pieces.erase( this );
}
};
关键是包含一些对象和仅仅能够迭代它们之间存在差异。如果使用最明显的方法创建和删除对象不使用容器,它们可能不应该在其中。