4

好吧,我不知道这是否可能,但事情是:

struct stPiece
{
  /* some stuff */
  stPiece *mother; // pointer to the piece that created this one
};

vector<stPiece> pieces;

是否可以从片段中删除“母亲”引用的片段,仅使用该指针作为参考?如何?

它会与其他参考文献混淆吗?(即,如果它不是向量中的最后一个元素,则通过将下一个元素移动到其他内存位置,而其他“*母亲”保持不变)。当然,我假设所有子片段都将被删除(所以我不需要更新任何指向同一个母亲的指针)。

谢谢!

4

5 回答 5

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。

我不确定我是否理解“假设所有子片段都将被删除”的意思。

于 2010-01-14T08:01:29.850 回答
2

如果您的mother指针直接指向pieces向量的元素,您将遇到各种麻烦。

删除一个元素pieces将移动元素在更高索引处的所有位置。即使插入元素也会使所有指针无效,因为向量可能需要重新分配它的内部数组,这可能会将所有元素转移到内存中的新位置。

要回答你的主要问题:你不能直接删除你有指针的元素,你首先需要搜索向量来找到它,或者计算它在向量中的索引。

不将指针存储到piecesasmother而是存储元素的索引会使其更加健壮,因此至少插入新元素不会破坏现有mother的 s。但是删除 frompieces仍然会将元素转移到新的索引。

使用std::listforpieces并将迭代器存储到其中mother可能是一种解决方案。std::list如果删除/添加了该列表中的其他元素,则迭代器不会失效。如果不同的元素可以具有相同mother的元素,那么在找出何时删除mother元素时仍然存在问题,那么使用boost::shared_ptr可能会更简单。

于 2010-01-14T05:24:54.500 回答
1

您编码的是单链树。您可能不希望一个对象包含您的所有stPieces,因为这会妨碍实现创建和删除语义。

我猜你想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 );
    }
};

关键是包含一些对象和仅仅能够迭代它们之间是有区别的。如果使用最明显的方法来创建和删除对象不是使用容器,那么它们可能不应该在其中。

于 2010-01-14T07:48:26.383 回答
1

是的,您可以删除母亲引用的那篇文章。

如果你删除了 ' mother ' 引用的片段,它的所有子元素中的母指针都会悬空,你必须注意这一点。

关于向量中元素的移动,您不需要这样做,它由向量类负责。

于 2010-01-14T04:55:13.173 回答
1

简短的回答:没有。

这些片段按值存储在向量中。因此,向量迭代器是指向片段的指针。这意味着,指向母片的指针与母片的向量迭代器相同。向量迭代器在插入(所有迭代器)和擦除(所有迭代器经过已擦除迭代器)时无效,这意味着内存位置将发生变化,并且几乎不可能保持所有指针的更新。

您可以将动态分配的片段存储在向量中,即:

vector<stPiece*> pieces

母指针不会随着片段被添加到向量中/从向量中移除而改变。缺点是:

  • 你现在必须管理内存(新建/删除每一块)
  • 它每块使用更多内存(块中的指针)
  • 它可能会更慢,因为您失去了空间局部性(缓存效率),因为它不再是 stPiece 对象的连续数组

后两点在您的应用程序中可能很重要,也可能不重要。

于 2010-01-14T05:42:54.330 回答