1

我有一个 struct Creature 和一个 struct Game。Game是Creature的“朋友”。在游戏中我有矢量生物;我通过一个名为 addC 的函数向该向量添加了一个生物 x

void addc (Creature& c){
    creatures.push_back(c);
}

现在我在另一个函数“foo”中,它是 struct Game 的公共方法。

void foo (Creature& c){
    ...
}

在该函数中,我需要从与来自生物 c 的某些信息相匹配的矢量生物中找到另一个生物。所以我在 Game 中创建了另一个名为 fooHelper 的公共方法

void fooHelper (char s, int x, int y){
    bool found = false;
    for (int i = 0; i < creatures.size() && (!found); ++i){
        Creature& c = creatures[i];
        if (x == c.x && y == c.y){
            c.s = s;
            found = true;
        }
    }
}

但是,当我检查第二个生物的“s”成员是否正在更新时,事实证明不是!我不明白我做错了什么,因为我是通过引用向量来推动的。我从向量中通过引用来获取生物。

游戏中的矢量看起来像这样

struct Game{
    private:
        vector<Creature> creatures;
    ...
}

struct Creature{
    private:
        char s;
        int x; int y;
    ...
}

任何帮助将非常感激!

4

2 回答 2

2

这个说法:

creatures.push_back(c);

将的副本存储c到您的向量中:标准容器具有值语义。如果您需要引用语义,您应该将指针存储到您的向量中。

通常使用智能指针是个好主意,使用哪一个取决于应用程序的所有权策略。在这种情况下,根据我可以从您的问题文本中获得的信息,让Game成为游戏中所有 s 的唯一所有者似乎是合理Creature的(因此是唯一负责所拥有Creatures 的生命周期的对象,并且在特别是在不再需要它们时销毁它们),所以std::unique_ptr应该是一个不错的选择:

#include <memory> // For std::unique_ptr

struct Game{
private:
    std::vector<std::unique_ptr<Creature>> creatures;
    ...
};

您的成员函数addc()将变为:

void addc(std::unique_ptr<Creature> c)
{
    creatures.push_back(std::move(c));
}

客户端会以这种方式调用它:

Game g;
// ...
std::unique_ptr<Creature> c(new Creature());
g.addc(std::move(c));

foohelper()另一方面,您的函数将被重写为如下内容:

void fooHelper (char s, int x, int y) {
    bool found = false;
    for (int i = 0; i < creatures.size() && (!found); ++i){
        std::unique_ptr<Creature>& c = creatures[i];
        if (x == c->x && y == c->y) {
            c->s = s;
            found = true;
        }
    }
}

最后,您的类Game可以将非拥有的原始指针(或引用)返回给需要访问存储的生物的客户端。

于 2013-04-02T22:59:20.970 回答
1

当您将生物参考推入矢量时,它正在制作副本。它是“Creature”类型的向量,因此它会根据您提供的参考进行复制。一种解决方案是保留一个生物指针向量。

编辑 - 这个问题有助于解释为什么你不能有参考向量的原因比我能解释的更好:为什么我不能制作参考向量?

于 2013-04-02T22:59:09.510 回答