好吧,我不知道这是否可能,但问题是:
struct stPiece
{
/* some stuff */
stPiece *mother; // pointer to the piece that created this one
};
vector<stPiece> pieces;
是否可以从片段中删除“mother”引用的片段,仅以该指针作为引用?如何?
它会与其他参考资料混淆吗? (即,如果它不是向量中的最后一个元素,则通过将下一个元素移动到其他内存位置,而其他“*mothers”保持不变)。当然,我假设所有子块都将被删除(因此我不需要更新任何指向同一个母块的指针)。
谢谢!
Well, I don't know if it is possible, but the thing would be:
struct stPiece
{
/* some stuff */
stPiece *mother; // pointer to the piece that created this one
};
vector<stPiece> pieces;
Is it possible to erase the piece referenced by 'mother' from pieces, having just that pointer as a reference? How?
Would it mess with the other references? (i.e. if it is not the last element in the vector, by shifting the next elements to other memory positions, while the other '*mothers' remain constant). Of course, I assuming that all the child pieces will be deleted (so I won't need to update any pointer that goes to the same mother).
Thanks!
发布评论
评论(5)
如果你的
mother
指针直接指向pieces
向量的元素,你将会遇到各种各样的麻烦。从
pieces
中删除一个元素将会移动索引较高的元素的所有位置。即使插入元素也会使所有指针无效,因为向量可能需要重新分配其内部数组,这可能会将所有元素转移到内存中的新位置。要回答您的主要问题:您无法直接删除指针指向的元素,您首先需要在向量中搜索以找到它,或者计算它在向量中的索引。
不将指针存储到
pieces
中作为mother
而是将元素的索引存储起来会使其更加健壮,这样至少插入新元素不会破坏现有的母亲的。但从
pieces
中删除仍然会将元素转移到新索引。使用
std::list
作为片段
并将迭代器存储到其中作为mother
可能是一个解决方案。如果删除/添加该列表中的其他元素,std::list
的迭代器不会失效。如果不同的元素可以具有相同的mother
,那么您仍然无法确定何时删除mother
元素,而不是使用boost::shared_ptr
会更简单。If your
mother
pointers point directly to elements of thepieces
vector you will get in all kinds of trouble.Deleting an element from
pieces
will shift all the positions of the elements at higher indexes. Even inserting elements can make all the pointers invalid, since the vector might need to reallocate it's internal array which might transfer all the elements to new positions in memory.To answer your main question: You can't delete the element you have the pointer to directly, you would first need search through the vector to find it, or calculate it's index in the vector.
Not storing pointers into
pieces
asmother
but instead the indexes of the elements would make it a bit more robust, so that at least inserting new elements could not break the existingmother
s. But deleting frompieces
would still shift elements to new indexes.Using a
std::list
forpieces
and storing iterators into that asmother
might be a solution. Iterators ofstd::list
are not invalidated if other elements are of that list are removed/added. If different elements can have the samemother
you still have a problem finding out when to remove themother
elements, than maybe usingboost::shared_ptr
would be simpler.目前尚不清楚整个数据结构是如何组织的以及会产生什么后果,但完全有可能通过指向该元素和向量本身的指针来从向量中删除该元素。您只需首先将指针转换为迭代器即可。例如,拥有一个向量
和一个指向该向量的指针,
您可以将指针转换为索引
,然后将索引转换为迭代器
,然后擦除元素
,仅此而已。
但是,在您的数据结构中,您可能有多个长期存在的指针指向同一个向量。任何从此类向量中删除元素的尝试都会立即使所有这些指针无效。理论上,如果你小心翼翼地做每件事,是可以“恢复”它们的有效性的,但这将影响到一个主要的 PITA。
我不确定我是否理解“假设所有子片段都将被删除”的意思。
It is not exactly clear how the entire data structure is organized and what the consequences are going to be, but it is perfectly possible to erase an element from the vector by having a pointer to that element and the vector itself. You just need to convert the pointer to an iterator first. For example, having a vector
and a pointer into that vector
you can convert the pointer to an index
then convert the index to an iterator
then erase the element
and that's it.
However, it appears that in your data structure you might have multiple long-lived pointers pointing into the same vector. Any attempts to erase elements from such vector will immediately invalidate all these pointers. It theoretically is possible to "restore" their validity, if you do everything carefully, but this is going to a major PITA.
I'm not sure I understand what you mean by "assuming that all the child pieces will be deleted".
是的,你可以删除妈妈引用的那篇文章。
如果您删除“mother”引用的块,则其所有子项中的mother 指针将变得悬空,您必须注意这一点。
关于向量中元素的移动,你不需要这样做,它由向量类处理。
Yes, you can erase the piece referenced by mother.
If you delete the piece referenced by 'mother', the mother pointer in all its children will become dangling, you'll have to take care of this.
About the shifting of elements in the vector, you need not do it, its taken care by the vector class.
简短的回答:不。
这些片段按值存储在向量中。因此,向量迭代器是指向片段的指针。这意味着,指向母块的指针与母块处向量的迭代器相同。向量迭代器在插入(所有迭代器)和擦除(所有经过擦除迭代器的迭代器)时无效,这意味着内存位置将发生变化,并且几乎不可能保持所有指针更新。
您可以在向量中存储动态分配的片段,即:
当向向量添加片段或从向量中删除片段时,母指针不会改变。缺点是:
后两点在您的应用程序中可能很重要,也可能不重要。
Short answer: no.
The pieces are stored in the vector by value. A vector iterator is therefore a pointer to a piece. This means, then, that a pointer to the mother piece is the same as the vector's iterator at the mother. Vector iterators are invalidated on insertion (all iterators) and erasure (all iterators past the erased iterator), which means memory locations will change and it will be nearly impossible to keep all the pointers updated.
You could store dynamically allocated pieces in the vector, i.e.:
The mother pointers won't change as pieces are added/removed to/from the vector. The downsides are:
The latter two points may or may not be important in your application.
您编写的代码是一棵单链接树。您可能不希望一个对象包含所有
stPiece
,因为这会妨碍实现创建和删除语义。我猜您想在所有孩子都消失后删除
mother
。关键点是包含某些对象和仅仅能够迭代它们之间是有区别的。如果使用最明显的方式创建和删除对象不使用容器,那么它们可能不应该在其中。
What you have coded is a singly-linked tree. You probably don't want an object to contain all your
stPiece
s, because that would get in the way of implementing creation and deletion semantics.I'm guessing that you want to delete
mother
after all the children are gone.The key point is that there's a difference between containing some objects and merely being able to iterate over them. If using the most obvious way to create and delete the objects isn't using the container, they probably shouldn't be in it.