我目前开始参加我的编程课程的学期项目 - 编程全自动驾驶模拟器。所有汽车都通过AI操纵,地图打印在控制台中。
第一张表要我们创建几个基本类:FCCompact(汽车),扫描仪(AI),ID(地形)和世界(地图)。
扫描仪目前在我的FCCompact类中实现为“HAS-A”,如下所示:
// FCCompact.h
class FCCompact
{
private:
struct fImpl;
fImpl *fImpl_;
/* ... */
// FCCompact.cpp
struct fImpl
{
Scanner scanner_;
/* ... */
};
有问题的扫描仪功能是
const ID& scanForID( int fovNumber, // How far it can see
FCCompact::Direction dir, // Direction car is facing
const Location& loc); // Location of car
到目前为止一切顺利。但是,整个地图位于World类中的容器vector< deque<ID> >
(1)中;我不确定如何访问它。
到目前为止发布的功能已由老师提供给我们,因此它们应该能够使用给定的参数来实现。我不知道该怎么做。
我的第一个想法是打电话给World::getID(Location &)
,但这不是静态的。使它静止后,它就不能再访问非静态成员了(呃,我忘记了)。我还做了一个调用非静态函数的静态函数;同样的问题(双duh)。
然后我抛弃了老师的指导原则并简单地传递了整个World
对象,但这也没有真正起作用。
我该怎么办?
请记住,这是技术上的功课,我不想要完整,合格的答案,甚至可以让我完全实现我想做的事情。我想尽可能多地从这个项目中学习,所以请指出我正确的方向。
(1):容器类型的奇怪选择?我想如果在控制台上打印世界,使用向量快速访问每一行将是有益的,因为不会插入或删除队列,访问时间也很棒。
另一方面,deque很容易用于访问范围,这是有利的,因为我会经常更改相邻列(沿x轴或y轴行驶的汽车)。这种选择没有迅速实现;我仍然在这个,一个列表或一个简单的向量之间徘徊。类
世界级
class ID;
class World
{
typedef std::pair<int, int> Location;
private:
// vector<deque<ID> > map
// int mapHeight, mapWidth
// string mapName
struct wImpl;
wImpl *pimpl_;
public:
World();
~World();
void create(const std::string& name = "FC-City");
int getHeight() const;
int getWidth() const;
ID getID(const Location& loc);
friend std::ostream& operator<<(std::ostream& os, World& world)
{
return os;
}
private:
void loadMap(std::string name = "FC-City");
private:
World(const World& other);
World& operator=(const World& other);
};
班级扫描仪
class ID;
class Scanner
{
typedef std::pair<int, int> Location;
public:
Scanner();
~Scanner();
const ID& scanForID( int fovNumber,
FCCompact::Direction dir,
const Location& loc);
private:
Scanner(const Scanner& other);
Scanner& operator==(const Scanner& other);
};
class FCCompact
class ID;
class FCCompact
{
typedef std::pair<int, int> Location;
public:
enum Direction
{
N, E, S, W,
NA = -1
};
private:
// Scanner scanner
// Location loc
// Direction dir
// ID id
struct FCCImpl;
FCCImpl *pimpl_;
public:
FCCompact( const ID& id,
const Location& loc,
const Direction& dir);
FCCompact( const char ch,
const Location& loc,
const Direction& dir);
const ID& getID() const;
Location getLoc() const;
Direction getDir() const;
void setDir( Direction& dir );
void step();
void hide();
void show();
};
班级ID
class ID
{
public:
enum Trait
{
Traversable,
NotTraversable,
Mobile,
Undef
};
private:
Trait trait_;
char appearance_;
public:
ID( char outputChar, Trait trait )
: appearance_(outputChar), trait_(trait)
{ }
ID( char outputChar )
: appearance_(outputChar), trait_(Trait::Undef)
{ }
char getToken() const { return appearance_; }
Trait getTrait() const { return trait_; }
void setTrait(Trait trait) { trait_ = trait; }
};
答案 0 :(得分:1)
听起来你想要类World
的单例模式。
class World {
public:
static World* getWorld();
private:
static World* _singleton;
};
您可以从构造函数和/或_singleton
初始化create()
。如果您愿意,getWorld()
可以返回引用(或在失败时抛出异常)。由您来思考:如果有人尝试创建多个世界会怎么样?你应该在程序结束时清理World::_singleton
吗?
答案 1 :(得分:1)
Scanner
应该有一个接受World
引用的构造函数;存储一个指向该参数的指针,以便稍后当你需要一个拥有一个世界的世界时。
请勿使用单身they're stupid。你可以使用全局,但这里确实没有必要。 Scanner
需要World
进行操作,因此您需要使用World
进行操作,以便进行操作:
struct bar;
struct foo
{
// foo cannot operate without a bar,
// therefore it needs to be supplied with
// one to be able to construct
foo(const bar& pBar) :
mBar(&pBar)
{}
void i_need_bar()
{
mBar->use_bar();
}
bar* mBar;
};