我的任务是
“我的狗,名叫巴迪,住在后院。当他看到一只猫或一只松鼠来看望时,他在夜间吠叫。如果他看到一只青蛙,他饿了,他就会吃它。如果他看到一只青蛙,他并不饿,他玩它。如果他已经吃了两只青蛙,并且仍然饿了,他会放手。如果他看到一只土狼,他会求助。有时他的朋友Spot停止了他们互相追逐。如果他看到任何其他动物,他只是看着它。
编写一个测试程序和一组跟踪所有后院活动的类,并将结果存储到给定夜晚的文件中。我希望你会有一个动物类,一只猫,狗,松鼠,土狼类继承自动物类。您需要记录他吃过多少只青蛙,每种类型的动物有多少来过,参加过多少次以及其他类似的细节。 “
您还需要编写一个测试程序,该程序将读取从其他测试程序生成的文件,并打印出他所看到的每种类型的动物数量,以及他在特定日期对他们所做的事情。用户需要输入日期,并且将读入并显示该日期的文件中的信息。
为您需要的程序添加任何其他功能,以便它涵盖列出的所有必需的编程概念。对此作业充满创意。
- 我们将使用类,数据抽象,继承,组合,指针,运算符重载和异常处理.-
#include <iostream>
#include <cstdlib>
using namespace std;
class animal{
public:
animal();
~animal();
void interactWithBuddy();
virtual int ID()
{
return ID;
}
};
class frog: public animal
{
public:
void interactWithBuddy();
void eat();
void play();
void letGo();
};
class dog: public animal
{
public:
void interactWithBuddy();
void chase();
};
class cat: public animal
{
public:
void interactWithBuddy();
void bark();
};
class coyote: public animal
{
public:
void interactWithBuddy();
void cryForHelp();
};
class squirrel: public animal
{
public:
void interactWithBuddy();
void bark();
};
class otherAnimal: public animal
{
public:
void interactWithBuddy();
void watch();
};
int main ()
{
srand(time(0));
int number;
std::cout << (rand() % 6 + 1) <<std::endl;
animal * a = new frog();
int z = a->ID();
animal * b = new dog();
int y = a->ID();
animal * c = new cat();
int x = a->ID();
animal * d = new coyote();
int w = a->ID();
animal * e = new squirrel();
int v = a->ID();
animal * f = new otherAnimal();
int u = a->ID();
return 0;
}
我知道代码只是一个shell,但我是在正确的轨道上吗?您如何建议对青蛙进行计数并确定它们是否被吃掉,玩耍或放手?此外,我想为每个动物子类分配一个数字,然后我可以在主函数中随机化,以便与分配相关联,但我不确定如何完成。提示和指示将非常受欢迎。
答案 0 :(得分:2)
你在基类中投入了太多。并非所有动物都可以做其他人所能做的所有事情。您的animal
课程应该只包含任何动物可以拥有/做的东西。所有特定于混凝土动物(即狗或青蛙)的东西都应放入相应的类别。例如,并非每个动物都可以bark()
,所以这个函数不应该在基类中。
您如何建议对青蛙进行计数并确定它们是否被吃掉,玩耍或放手?
因为它可以看到青蛙的狗,所以将一个计数器放入dog
课程是有意义的。
另外,我想为每个动物子类分配一个我可以的数字 然后在主函数中随机化以便与...相关联 任务,但我不确定如何做到这一点。
我不太明白你的意思。你的意思是你想为每个班级制作标识符吗?如果是的话,你为什么需要这样做?
<强> UPD:强>
是的,这是一种正确的方法。最简单的方法是为每只动物分配1到6的数字,然后当您需要确定出现哪一个时,生成[1,6]
范围内的随机数。要为动物指定数字,您应该添加int id;
之类的字段,并在每个类中为其指定不同的值。
UDP 2:
这就是多态性发挥作用的地方。首先,要初始化类的const成员,需要将其设置为静态。这是一个简单的例子:
class base
{
public:
static const int ID = -1;
};
class derived: public base
{
public:
static const int ID = 1;
};
现在基类的每个对象的ID都是-1,派生类的每个对象的的ID都是1.但是,如果你尝试从像这样的基类指针中使用它:
base * a = new derived();
int t = a->ID;
你总是得到-1,因为基类指针不知道它指向它的是什么。 要获得正确的ID,您需要创建一个虚函数:
virtual int getId(){ return ID; }
现在,如果你愿意的话
base * a = new derived();
int t = a->getID();
您将始终从“真实”类型a
点获取正确的ID。
答案 1 :(得分:1)
我建议你把随机逻辑放在工具之外......分离关注点。然后你可以有一个程序只从标准输入读取一系列动物名称,执行动作并记录它需要的任何内容,然后当它检测到文件结束时打印一个摘要报告。你可以简单地测试它:
echo cat frog frog squirrel frog | buddy_simulator
如果需要,您可以创建一个程序来随机化一些输入。
基本逻辑应该是:
std::string animal_name;
while (std::cin >> animal_name)
{
// do something animal_specific
}
// do reporting
可以使用接受animal_name
参数的工厂方法创建动物特定行为,并将适当的Animal*
返回到新堆分配的动物对象。然后你可以打电话给p->suffer_buddy();
,它会更新一个静态成员“这个动物被看见的时间”计数器,打印出好友喜欢做的事情(在这个目击中)。如果这是第一次看到动物,您可以将指针存储在vector
中的main()
,这样当您想要执行摘要报告时,您可以为每个动物调用p->report()
你遇到的动物类型。例如,Frog::report()
可能类似于:
void Frog::report()
{
std::cout << "of " << count_ << " frogs, " << eaten_ << " eaten, " << played_with_ << " played with, " << let_go_ << " let go\n";
}
使用这么多静态变量有点难看,但它更容易让它像这样工作。
(不幸的是,行为被严格指定 - 你如何判断好友是否饿了?根本没有指明,所以你必须做出一些假设(并记录下来)或者让你的老师指明这一点。)
这都是非常愚蠢的,但是那么使用多态层次结构来建模这个问题,所以你去....