使用现有类设计实现功能的问题
我目前已经开始了我的编程课程的学期项目——对完全自动驾驶模拟器进行编程。所有汽车均通过人工智能驾驶,地图打印在控制台上。
第一张表要求我们创建几个基本类:FCCompact(汽车)、Scanner(AI)、ID(地形)和 World(地图)。
扫描仪目前在我的 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
到目前为止都很好。然而,整个地图位于一个容器 vector< 中。双端队列
(1)在类World中;我不知道如何访问它。
目前贴出的功能都是老师给我们的,所以按照给定的参数应该可以实现。我只是不知道该怎么做。
我的第一个想法是调用 World::getID(Location &)
,但它不是静态的。将其设为静态后,它无法再访问非静态成员(呃,我忘了这一点)。我还制作了一个调用非静态函数的静态函数;同样的问题(双废话)。
然后我扔掉了老师的指南,只是简单地传入了整个 World
对象,但这也没有真正起作用。
我能做些什么?
请记住,这在技术上是一项作业,我不需要完整的、合格的答案,甚至可以让我完整地实现我想做的事情。我想从这个项目中学到尽可能多的东西,所以请为我指明正确的方向。
(1):容器类型的选择很奇怪?我认为如果世界被打印在控制台上,那么使用向量快速访问每一行将是有益的,因为不会插入或删除队列,并且访问时间非常短。
另一方面,双端队列可以方便地访问范围,这是有利的,因为我会经常更改相邻的列(沿 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);
};
类 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; }
};
I've currently started on my semester project for my programming course- programming a fully autonomous driving simulator. All cars are steered through AI and the map is printed in the console.
The first sheet wants us to create a couple of basic classes: FCCompact (The car), Scanner (AI), ID (terrain), and World (The map).
The Scanner is currently implemented as a "HAS-A" in my FCCompact class like so:
// FCCompact.h
class FCCompact
{
private:
struct fImpl;
fImpl *fImpl_;
/* ... */
// FCCompact.cpp
struct fImpl
{
Scanner scanner_;
/* ... */
};
The scanner function in question is
const ID& scanForID( int fovNumber, // How far it can see
FCCompact::Direction dir, // Direction car is facing
const Location& loc); // Location of car
So far so good. However, the entire map is located in a container vector< deque<ID> >
(1) in the class World; I'm not sure how to access it.
The functions posted so far have been given to us by the teacher, so they should be able to be implemented with the parameters given. I just have no clue how to do that.
My first idea was to call World::getID(Location &)
, but it's not static. Upon making it static, it can no longer access non-static members (duh, I forgot that). I have also made a static function that calls a non-static function; same problem (double duh).
Then I tossed the teacher's guidelines and simply passed in the entire World
object, but that didn't really work either.
What can I do?
Please keep in mind that this is technically homework and that I do not want full, qualified answers that even gives me the entire implementation of what I want to do. I want to learn as much as possible from this project, so please just point me in the right direction.
(1): Weird choice for a container type? I figured if the world is printed on the console, quick access to each row with a vector would be beneficial, since there will be no insertion or deletion of queues and the access time is brilliant.
A deque, on the other hand, is handily for accessing ranges, which is favorable since I will frequently change adjacent columns (cars driving along the x- or y-axis). This choice did not come swiftly; I'm still torn between this, a list, or a simple vector again.
Classes
class World
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 Scanner
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();
};
class 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; }
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Scanner
应该有一个接受World
引用的构造函数;存储一个指向该参数的指针,以便稍后当您需要一个世界时,您就拥有了一个。不要使用单例,他们很蠢。您可以使用全局,但这里确实没有必要。
Scanner
需要一个World
来操作,因此您可以使用一个World
来构造它来操作:Scanner
should have a constructor that accepts a reference to aWorld
; store a pointer to that argument so later when you need a world you have one.Don't use a singleton, they're stupid. You could use a global but there really isn't a need here. A
Scanner
needs aWorld
to operate on, ergo you construct it with aWorld
to operate on:听起来您想要类
World
的单例模式。您可以从构造函数和/或
create()
初始化_singleton
。如果您愿意,getWorld()
可以返回引用(或在失败时抛出异常)。由你来思考:如果有人尝试创造多个世界怎么办?您应该在程序结束时清理World::_singleton
吗?Sounds like you want the singleton pattern for class
World
.You can initialize
_singleton
from your constructor and/orcreate()
.getWorld()
can return a reference (or throw an exception on failure) if you prefer. Up to you to think about: what if somebody tries creating multiple Worlds? Should you clean upWorld::_singleton
at the end of the program?