当他们的运动功能被调用时,他们只需要找到其他蛇和食物的位置的设施。在初始化时无需知道它们的存在!
因此,您可以拥有蛇集合和食物集合,并将对这些集合的引用传递给任何新创建的蛇和食物。只需先创建这些集合。
你可以通过另一个类来做到这一点,也许它也可以作为一个工厂。
class GameManager;
class Snake
{
friend class GameManager;
public:
int getX() { return _x; }
int getY() { return _y; }
void setPosition(int x, y) { /* ... */ }
private:
Snake(GameManager* manager, int x, int y) : _manager(manager), _x(x), _y(y) {}
GameManager* _manager;
int _x, _y;
};
class GameManager
{
public:
const std::vector<Snake*>& Snakes() { return _snakes; }
Snake* SpawnSnake(int x, int y)
{
Snake* newSnake = new Snake(this, x, y);
snakes.push_back(newSnake);
return snake;
}
private:
std::vector<Snake*> _snakes;
};
(只是一个例子。代码未经测试,看它是否真的编译。E&OE)
因为构造函数是私有的GameManager
,所以确保所有创建的蛇都在蛇向量中找到。Snake
每条蛇都可以调用_manager.Snakes()
以获取包含游戏中所有其他蛇的向量,然后它可以单独查询它们的位置。这也很容易推广到支持食品。
与其他答案中建议的“构造初始化”模式相比,这具有很小的优势,因为它确保当您获得一个新Snake
对象时,它实际上已经准备好使用......这个例子并不完全是 RAII,但它需要一个使其合理异常安全的最小努力。