存储std :: set对象的引用/指针

时间:2012-11-20 22:12:17

标签: c++

我正在制作一个关于弹珠的游戏,它使用结构来描述大理石属性:

struct Marble
{
Color color;
int weight;
//Other customizable marble properties
};

我目前正在使用std::vector来跟踪哪些弹珠位于游戏板上的哪个位置:

std::vector<Marble> m_marbles;

在任何时候,我都可以通过索引到矢量来检查大理石的属性。检查位置20的大理石颜色:

m_marbles[20].color;

用户可以创建自定义大理石并将其添加到游戏板。如果我想在游戏板上添加一个新的大理石,我会创建一个新的struct对象并将其推送到向量上:

Marble m;

//Fill struct with marble information

m_marbles.push_back(m)

问题是游戏板非常大(成千上万的弹珠),而且许多弹珠都完全一样。

假设游戏板上有4000个位置。也许其中3000个是红色大理石,重量为1.0。在当前的解决方案中,3000个等效的Marble对象占据了向量中的空间。

由于用户可以定义自己的大理石类型,因此我不能只对所有可能的大理石类型进行硬编码,然后让向量存储指向相应大理石对象的指针。

我在考虑使用std::set来存储不同的大理石类型。然后,当用户去创建他的自定义大理石时,他可以尝试将其插入到集合中。如果已存在相同类型的大理石,则不会浪费记忆。

我的问题是,如何将引用存储到std::set?例如,假设我的集合包含这些大理石类型:

{RedMarble, BlueMarble, StrangeMarble, ConfusedMarble}

现在我想将红色大理石分配到游戏板上的第20位:

m_marbles[20] = ?

我还想检查31号位置大理石的颜色:

m_marble[31].color;

是否可以这样使用套装? find和insert函数返回迭代器,但如果我在集合中插入更多项目,那么它们不会失效吗?

4 个答案:

答案 0 :(得分:0)

你应该让向量包含指针到Marble结构:

std::vector<Marble*> m_marbles;

指针不占用太多空间,您仍然可以使用Marble作为基类。

答案 1 :(得分:0)

如果游戏板真的只有几千个地方,我不会在乎浪费空间。例如

10000 places * sizeof(Marble) = 10000 * 100 bytes ~ 1 MB

按照今天的标准,记忆力不是很大。

如果它可能变得非常大,那么你确实可以将你的独特大理石存储在一个集合中并用指针引用它们,就像@BenRuijl已经显示的那样。

答案 2 :(得分:0)

构建一个类Marble,其中包含一个指向MarbleType的指针,用于定义每个大理石的属性(对于每种大理石,您有一个MarbleType个实例)。向量可能包含Marble或共享指向Marble的指针或唯一指针。如果Marble类很小(飞重模式),则不会浪费空间,但仍然有一个干净灵活的解决方案。大理石类型可以命名(例如通过字符串)并存储在std::map

答案 3 :(得分:0)

是的,你可以做你想做的事。您可以在向量中存储指针,指针指向集合中的大理石。或者你可以在迭代器中存储迭代器,迭代器再次指向你集合中的Marbles。

以下是我用指针做的方法:

// A useful helper funtction -- not required, but useful.
const Marble* Helper(const Marble& m) {
  static std::set<Marble> uniqueMarbles;
  return &*(uniqueMarbles.insert(m).first);
}

// A vector of pointers to marbles
std::vector<const Marble*> m_marbles;

// You can pass temporaries to the helper function, and it returns a permanent pointer
m_marbles.push_back(Helper(Marble(RED, 1.0));

Marble m;
m.setColor(BLUE);
m_marbles.push_back(Helper(m));


// You can reference your marbles
Color c = m_marbles[i]->getColor();

// Hopefully the following will produce a compiler error message
m_marbles[i]->setColor(GREEN); // Oops, m_marbles holds const pointers