2010-08-23 79 views
1

我的问题最好用代码示例说明,所以让我们开始吧:C++:深层复制指针(高效)

class Game 
{ 
    // All this vector does is establish ownership over the Card objects 
    // It is initialized with data when Game is created and then is never 
    // changed. 
    vector<shared_ptr<Card> > m_cards; 

    // And then we have a bunch of pointers to the Cards. 
    // All these pointers point to Cards from m_cards. 
    // These could have been weak_ptrs, but at the moment, they aren't 
    vector<Card*> m_ptrs; 

    // Note: In my application, m_ptrs isn't there, instead there are 
    // pointers all over the place (in objects that are stored in member 
    // variables of Game. 
    // Also, in my application, each Card in m_cards will have a pointer 
    // in m_ptrs (or as I said, really just somewhere), while sometimes 
    // there is more than one pointer to a Card. 
} 

现在我要做的就是制作这个Game类的深层副本。我创建了一个带有新shared_ptrs的新向量,它指向新的Card对象,它们是原始Card对象的副本。那部分很容易。

然后问题开始了,应该更新m_ptrs的指针以指向m_cards中的卡,这不是一项简单的任务。

我能想到的唯一方法是创建一个地图并在复制m_cards(使用map[oldPtr] = newPtr)时填充它,然后使用它来更新m_ptrs。但是,这只是O(m * log(n))m = m_ptrs.size(); n = m_cards.size())。因为这将是一个非常常规的操作*我想有效地做到这一点,我觉得它应该可以在O(m)中使用自定义指针。但是,我似乎无法找到一种有效的方法。有谁做的?

*它用于为AI创建一个测试平台,让它“尝试”不同的动作


编辑:我想补充一点接受答案,因为我还没有。我等到我回到这个项目之后(因为我在这个项目上做了太多工作,所以我走上了一条小道 - 如果你为了好玩而这么做就必须保持乐趣),所以在我接受之前可能还需要一段时间一个答案。不过,我会接受一些答案,所以不要担心:P


编辑nr 2:我还没有回到这个项目。现在,我正在考虑采用O(m * log(n))方式而不是抱怨,然后再看看它是否需要更快。但是,由于我最近花了一些时间来学习我的模式,我也认为我真的需要重构一下这个项目。哦,我可能只是花了一些时间用我掌握的所有新知识来解决这个问题。因为没有一个答案说“只是坚持使用hashmap,稍后再看它是否真的需要更快”(如果有,我实际上会非常失望,因为它不是我的问题的答案),我是推迟回答答案,直到我回到这个项目。


编辑nr 3:我仍然没有回到这个项目。更确切地说,它已被无限期搁置。我很确定我现在不会让我的头脑过于弯曲O(m * log(n)),然后如果事实证明这是个问题,那么也许稍后再看看它。但是,这对我的问题来说不是一个好的答案,因为我明确要求提高性能。我不想再接受答案,我选择了最有帮助的答案并接受了答案。

+0

我不确定我是否理解你为什么需要使用相同数据的2个向量。听起来像是我对数据缺陷的重复。请解释你为什么需要/想要这个? – 2010-08-23 14:37:22

+0

@John Dibling:请**请**阅读。指针数组是简化问题以简化问题。实际上它不存在 - 相反,指针分布在Game所拥有的许多类中。这是在问题。此外,它是(更详细)在本页其他地方。 – Jasper 2010-08-25 08:14:20

+0

当我做一些类似的事情时,我使用了一个映射来映射oldptrs到newptrs,虽然这对我来说并不重要,因为映射只在拷贝时使用,所以不需要优化。你认为你可以重构你的项目,以帮助你的更改更容易介绍或什么? – n1ckp 2010-08-28 14:03:35

回答

3

将指针存储为索引。 正如你所说,他们都指向m_Cards这是一个可以被索引的向量(是正确的英语吗?)。 要么你这样做只是为了存储并在加载时将它们转换回指针。 或者您可能会考虑通常使用索引而不是指针。

+0

kaptnole,我编辑根据我的浏览器spillchucker。哦,和'+ 1',因为我同意。 – sbi 2010-08-23 10:13:31

+0

所以基本上,我创建了一个存储向量和索引的引用的指针。听起来不错 - 如果做得很好,可以用真正的指针语法来完成。我需要研究具体情况,但听起来不错。 – Jasper 2010-08-23 10:42:31

+0

由于除了使用多个Card *之外,我还遇到了一些问题,因此我还使用了一些SpecialCard *(其中SpecialCard继承自Card),这也指向m_cards的成员,并且还应该被更新。但说实话,那不是问题所在。 – Jasper 2010-09-07 14:42:36

0

怎么样保持卡元素索引而不是指针:

使用索引
 
vector<int> m_indexes; 

... 

Card* ptr = &m_cards[m_indexes[0]]; 

矢量可以在不改变被复制。

+0

我没有在解决方案上销售,因为它需要我将几十个类的引用分发给m_cards,因为看到卡指针并不是真正在同一个类中使用,而是遍布整个地方。但它确实解决了这个问题。 – Jasper 2010-08-23 10:28:12

+0

@Jasper为什么你必须提交m_cards的引用?你还不能把实际的指针交给其他类吗? – TJMonk15 2010-08-23 13:28:18

+0

,因为样本被简化了,指针实际上并不驻留在同一个类中 - 它们驻留在Game所拥有的类中 - 所有这些指针都需要指向新的Card对象。因此,使用索引而不是指针,但是使用除了Game类之外的其他类中的指针(其中除了其中一个之外的其他类:P)并不能很好地解决问题。 – Jasper 2010-08-23 14:47:13