C++语言学习笔记8:宠物小屋

宠物小屋 - 需求

  • 动物:猫 (CCat)、狗(CDog)、蛇(CSnake)

    • 包含名字(m_strName)、颜色(m_strColor)、年龄(m_nAge)。
  • 笼子类(CCage):负责装动物,每个笼子的编号不能相同,一个笼子只装一个动物。

  • 房子类(CHouse):负责存放装动物的笼子。

  • 人(CPeople):负责花钱买动物,造笼子,将动物放在笼子中,存放到房子里,杀死某个笼子动物,销毁某个笼子(如果有动物一并销毁),查看某个或所有笼子动物,和某个动物玩耍。

getline

控制台程序,通过输入命含,可以进行简单的人机交互。
提示:获取输入字符可以用
    				string:getline(cin,cmd);	//获取输入的命令(阻塞等待)。

#include<string>
basic istream<_Elem,_Traits>& getline(
				basic_istream<_Elem,_Traits>&			_Istr,
    			basic_string<_Elem,_Traits,_Alloc>&     _Str,
   				const _Elem								_Delim)
    
_Istr : 表示一个输入流,譬如cin.
_Str : 将输入流读取的字符串放到_Str中。 
_Delim : 遇到这个学符就停正读取,不设置默认为'\n'

值传递vs指针or引用

//尽量不用值传递,用引用or指针
//原因:值传递时并不是直接把变量a=1传过去,而是在函数里面重新创建了一个跟a的类型一样的变量b,让b=1,因此涉及到变量创建和变量赋值的过程,如果该变量类型是一个很大的类,那么会创建很久赋值很久 ,性能损耗比较大。而指针的话就是创建一个指针和赋值一个地址,性能损耗相对来说小很多,引用则是创建一个指向变量a的符号b~

类图

宠物小屋类图

头文件

#pragma once
#include <string>
using namespace std;

class CAnimal
{
public:
	CAnimal(void);
	virtual ~CAnimal(void);
public:
	int m_nAge;
	string m_strName;
	string m_strColor;
public:
	virtual void PlayAnimal() = 0;	//纯虚函数,抽象类,不可以定义对象
	void InitAnimal(string& name, string& color, int age);
	void ShowAnimal();
};
#pragma once
#include "Animal.h"

class CCage
{
public:
	CCage(void);
	~CCage(void);
public:
	CAnimal* m_pAni;
	int m_nId;
public:
	void InitCage(int id);
};
#pragma once
#include "Animal.h"

class CCat :
    public CAnimal
{
public:
    CCat(void);
    ~CCat(void);
public:
    virtual void PlayAnimal();
};
#pragma once

#define ANIMAL_KIDN_CAT			1
#define ANIMAL_KIDN_DOG			2
#define ANIMAL_KIDN_SNAKE		3

#define ANIMAL_COST_CAT			400
#define ANIMAL_COST_DOG			600
#define ANIMAL_COST_SNAKE		1000

#define PEOPLE_MONEY			2000

#define CMD_BUY_ANIMAL_DOG		"buy dog" 
#define CMD_BUY_ANIMAL_CAT		"buy cat" 
#define CMD_BUY_ANIMAL_SNAKE	"buy snake" 

#define CMD_PROGRAM_QUIT		"quit"
#define CMD_LOOK_ANIMAL			"look"
#define CMD_KILL_ANIMAL			"kill"
#define CMD_DESTORY_CAGE		"destory"
#define CMD_PLAYWITH_ANIMAL		"play"
#define CMD_SHOW_PEOPLE			"show"

#define CMD_HELP				"help"
#pragma once
#include "Animal.h"

class CDog :
    public CAnimal
{
public:
	CDog(void);
	~CDog(void);
public:
	virtual void PlayAnimal();
};
#pragma once
#include <list>
using namespace std;
#include "Cage.h"

class CHouse
{
public:
	CHouse(void);
	~CHouse(void);
public:
	list<CCage*> m_lstCage;
};
#pragma once
#include <string>
using namespace std;
#include "Animal.h"
#include "Cage.h"
#include "House.h"

class CPeople
{
public:
	CPeople(void);
	~CPeople(void);
public:
	int m_nMoney;
	string m_nstrName;
public:
	void InitPeople(string& name, int money);
						//尽量不用值传递,用引用or指针
						//原因:值传递时并不是直接把变量a=1传过去,而是在函数里面重新创建了一个跟a的类型一样的变量b,让b=1,因此涉及到变量创建和变量赋值的过程,如果该变量类型是一个很大的类,那么会创建很久赋值很久 ,性能损耗比较大。而指针的话就是创建一个指针和赋值一个地址,性能损耗相对来说小很多,引用则是创建一个指向变量a的符号b~
	void ShowPeople();
	bool BuyAnimal(CAnimal* pAni, int AnimalKind);
	CCage* CreateCage();
	void PushAnimal(CCage* pCage, CAnimal* pAnimal);
	void PushCage(CHouse* pHouse, CCage* pCage);
	void LookAnimal(CHouse* pHouse, int Id);
	void PlayWithAniamal(CHouse* pHouse, int Id);
	void KillAnimal(CHouse* pHouse, int Id);
	void DestoryCage(CHouse* pHouse, int Id);
};
#pragma once
#include "Animal.h"
class CSnake :
    public CAnimal
{
public:
	CSnake(void);
	~CSnake(void);
public:
	virtual void PlayAnimal();
};

源文件

#include "Animal.h"
#include <iostream>
using namespace std;

CAnimal::CAnimal(void) {
	m_strColor = "	";
	m_strName = "	";
	m_nAge = 0;
}

CAnimal::~CAnimal(void) {
	m_strColor = "	";
	m_strName = "	";
	m_nAge = 0;
}

void CAnimal::InitAnimal(string& name, string& color, int age) {
	m_strName = name;
	m_strColor = color;
	m_nAge = age;
}

void CAnimal::ShowAnimal() {
	cout << "Animal info:name=" << m_strName << ",color=" << m_strColor << ",age=" << m_nAge << endl;
}
#include "Cage.h"
#include <iostream>
using namespace std;

CCage::CCage(void) {
	m_pAni = NULL;
	m_nId = 0;
}

CCage::~CCage(void) {

}

void CCage::InitCage(int id) {
	m_nId = id;
}
#include "Cat.h"
#include <iostream>
using namespace std;

CCat::CCat(void) {

}

CCat::~CCat(void) {

}

void CCat::PlayAnimal() {
	cout << "猫猫喵喵叫~" << endl;
}
#include "Dog.h"
#include <iostream>
using namespace std;

CDog::CDog(void) {

}

CDog::~CDog(void) {

}

void CDog::PlayAnimal() {
	cout << "狗狗汪汪叫~" << endl;
}
#include "House.h"

#include <iostream>
using namespace std;

CHouse::CHouse(void) {
	m_lstCage.clear();
}

CHouse::~CHouse(void) {
	list<CCage*>::iterator ite = m_lstCage.begin();
	while (ite != m_lstCage.end()) 
	{
		//先删除动物,再删除笼子,最后回收清空链表
		if ((*ite)->m_pAni) //判断有没有动物
		{
			delete (*ite)->m_pAni;
			(*ite)->m_pAni = NULL;
		}
		delete(*ite);
		(*ite) = NULL;

		//ite++;//方式1
		ite = m_lstCage.erase(ite);	//方式2
		//擦除,返回删除的下一个节点,其功能等同于ite++
	}
	m_lstCage.clear();
}
#include "People.h"
#include "Def_config.h"
#include <iostream>
using namespace std;

CPeople::CPeople(void) {
	m_nMoney = 0;
	m_nstrName = "	";
}

CPeople::~CPeople(void) {
	m_nMoney = 0;
	m_nstrName = "	";
}

void CPeople::InitPeople(string& name, int money) {
	m_nMoney = money;
	m_nstrName = name;
}

void CPeople::ShowPeople() {
	cout << "people info:name" << m_nstrName << ",money=" << m_nMoney << endl;
}

#define BUY_ANIMAL(ANIMAL_COST,TIPS)\
	if (m_nMoney - ANIMAL_COST < 0){\
	cout << TIPS << endl;\
	return false;\
	}\
	else\
	{\
		cout << "购买成功" << endl;\
	}\
	m_nMoney -= ANIMAL_COST;

bool CPeople::BuyAnimal(CAnimal* pAni, int AnimalKind) {
	if (pAni == NULL) 
	{
		cout << "没有动物啦,不用买了" << endl;
		return false;
	}
	switch (AnimalKind)
	{
	case ANIMAL_KIDN_CAT:
	{
		//if (m_nMoney - ANIMAL_COST_CAT < 0) {
		//	cout << "买猫咪钱不够噢~攒攒钱再来吧~" << endl;
		//	return false;
		//}
		//m_nMoney -= ANIMAL_COST_CAT;

		BUY_ANIMAL(ANIMAL_COST_CAT, "买猫咪钱不够噢~攒攒钱再来吧~")
	}
	break;
	case ANIMAL_KIDN_DOG:
	{
		BUY_ANIMAL(ANIMAL_COST_DOG, "买狗狗钱不够噢~攒攒钱再来吧~")
	}
	break;
	case ANIMAL_KIDN_SNAKE:
	{
		BUY_ANIMAL(ANIMAL_COST_SNAKE, "买小蛇钱不够噢~攒攒钱再来吧~")
	}
	break;
	}
	return true;
}

CCage* CPeople::CreateCage() {
	CCage* pCage = new CCage;
	int Id = 0;
	do 
	{
		cout << "请输入笼子编号(编号应>0):" << endl;
		cin >> Id;
	} while (Id <= 0);
	pCage->InitCage(Id);

	return pCage;
}

void CPeople::PushAnimal(CCage* pCage, CAnimal* pAnimal) {
	if (pCage == NULL) 
	{
		cout << "没有笼子,不能装动物啊" << endl;
		return;
	}
	if (pAnimal == NULL)
	{
		cout << "没有动物,不用装笼子啊" << endl;
		return;
	}
	pCage->m_pAni = pAnimal;
	cout << "动物成功装进笼子啦" << endl;
}

void CPeople::PushCage(CHouse* pHouse, CCage* pCage) {
	if (pHouse == NULL) 
	{
		cout << "没有房子啊" << endl;
		return;
	}
	if (pCage == NULL) 
	{
		cout << "没有笼子啦" << endl;
	}
	pHouse->m_lstCage.push_back(pCage);
	cout << "笼子成功放到房子里去啦" << endl;
}

void CPeople::LookAnimal(CHouse* pHouse, int Id) {
	if (pHouse == NULL)
	{
		cout << "没有房子啊,当然也没有笼子和动物,你想看空气吗?" << endl;
		return;
	}
	//查看笼子,id==0的话,是查看所有笼子,id=1就查看1号笼子以此类推~
	if (Id == 0)//代表查看所有笼子里的动物
	{
		list<CCage*>::iterator ite = pHouse->m_lstCage.begin();
		while (ite != pHouse->m_lstCage.end()) 
		{
			if (*ite)//先判断有没有笼子
			{
				cout << "笼子编号:ID=" << (*ite)->m_nId << "	";
				if ((*ite)->m_pAni) //判断笼子里有没有动物
				{
					(*ite)->m_pAni->ShowAnimal();
				}
				else {
					cout << "没有动物呀~" << endl;
				}
			}
			ite++;
		}

	}
	else {//遍历匹配某号笼子里的动物
		list<CCage*>::iterator ite = pHouse->m_lstCage.begin();
		while (ite != pHouse->m_lstCage.end()) 
		{
			if (*ite) 
			{
				if ((*ite)->m_nId == Id) //匹配成功
				{
					cout << "笼子编号:ID=" << (*ite)->m_nId << "	";
					if ((*ite)->m_pAni) //判断笼子里有没有动物
					{
						(*ite)->m_pAni->ShowAnimal();
					}
					else {
						cout << "没有动物呀~" << endl;
					}
					return;
				}
			}
			ite++;
		}
	}
}

void CPeople::PlayWithAniamal(CHouse* pHouse, int Id) {
	if (pHouse == NULL)
	{
		cout << "没有房子啊,当然也没有笼子和动物,你是个孤儿,自己玩儿吧" << endl;
		return;
	}
	list<CCage*>::iterator ite = pHouse->m_lstCage.begin();
	while (ite != pHouse->m_lstCage.end())//遍历
	{
		if ((*ite) && (*ite)->m_nId == Id) //匹配到笼子
		{
			if ((*ite)->m_pAni)
			{
				cout << "name = " << m_nstrName << "正在玩儿~" << "	";
				(*ite)->m_pAni->PlayAnimal();
			}
			return;
		}
		ite++;
	}
	cout << "没有找到笼子和动物一块儿玩儿~" << endl;
}

void CPeople::KillAnimal(CHouse* pHouse, int Id) {
	if (pHouse == NULL)
	{
		cout << "没有房子啊,当然也没有笼子和动物,不需要杀死or抛弃动物了,你已经是孤儿了~" << endl;
		return;
	}
	list<CCage*>::iterator ite = pHouse->m_lstCage.begin();
	while (ite != pHouse->m_lstCage.end())//遍历
	{
		if ((*ite) && (*ite)->m_nId == Id) //匹配到笼子
		{
			if ((*ite)->m_pAni) 
			{
				delete (*ite)->m_pAni;
				(*ite)->m_pAni = NULL;
			}
			cout << "成功杀死动物" << endl;
			return;
		}
		ite++;
	}
	cout << "没有匹配到笼子,杀死动物失败" << endl;
}

void CPeople::DestoryCage(CHouse* pHouse, int Id) {
	if (pHouse == NULL)
	{
		cout << "没有房子啊,当然也没有笼子,没办法销毁笼子嗷~" << endl;
		return;
	}
	list<CCage*>::iterator ite = pHouse->m_lstCage.begin();
	while (ite != pHouse->m_lstCage.end())//遍历
	{
		if ((*ite) && (*ite)->m_nId == Id) //匹配到笼子
		{
			//先判断有无动物,有的话删除动物
			if ((*ite)->m_pAni) 
			{
				delete (*ite)->m_pAni;
				(*ite)->m_pAni = NULL;
			}
			//销毁笼子
			delete (*ite);
			(*ite) = NULL;
			
			//删除链表节点
			pHouse->m_lstCage.erase(ite);

			cout << "成功销毁笼子" << endl;
			return;
		}
		ite++;
	}
	cout << "没有找到需要销毁的笼子" << endl;
}
#include "Snake.h"
#include <iostream>
using namespace std;

CSnake::CSnake(void) {

}

CSnake::~CSnake(void) {

}

void CSnake::PlayAnimal() {
	cout << "蛇嘶嘶吐舌~" << endl;
}

主函数

#include "People.h"
#include "House.h"
#include "Def_config.h"
#include "Dog.h"
#include "Cat.h"
#include "Snake.h"

#include <sstream>
#include <iostream>
using namespace std;

#define DEF_BUY_ANIMAL_PART(ANI_CLASS,ANI_KIND)\
		pAni = new ANI_CLASS;\
		GetAnimalAttr(Animalname, color, age);\
		pAni->InitAnimal(Animalname, color, age);\
		pPeople->BuyAnimal(pAni, ANI_KIND);

void GetAnimalAttr(string& Animalname, string& color, int &age) {
	cout << "请输入动物信息:1.名字 2.颜色 3.年龄(例:小娃 白 5)" << endl;
	string AnimalAttr;
	getline(cin, AnimalAttr);

	stringstream ss(AnimalAttr);
	string s;
	int i = 0;
	while (ss >> s)
	{
		switch (i)
		{
		case 0: {
			Animalname = s;
		}
			  break;
		case 1: {
			color = s;
		}
			  break;
		case 2: {
			age = atoi(s.c_str());//字符串转int类型
		}
			  break;
		}
		i++;
	}//以空格为标记点 遍历三次 依次把名字 颜色 年龄获取到
}

void showHelp() {

	cout << CMD_BUY_ANIMAL_DOG << ":买狗" << endl;
	cout << CMD_BUY_ANIMAL_CAT << ":买猫" << endl;
	cout << CMD_BUY_ANIMAL_SNAKE << ":买蛇" << endl;
	cout << CMD_PROGRAM_QUIT << ":退出程序" << endl;
	cout << CMD_LOOK_ANIMAL << ":查看动物信息" << endl;
	cout << CMD_KILL_ANIMAL << ":杀死动物" << endl;
	cout << CMD_DESTORY_CAGE << ":销毁笼子及笼内动物" << endl;
	cout << CMD_PLAYWITH_ANIMAL << ":和动物玩耍" << endl;
	cout << CMD_SHOW_PEOPLE << ":展示人物信息" << endl;
	cout << CMD_HELP << ":帮助文档" << endl;

}

int main(){
	
	CPeople* pPeople = new CPeople;
	CHouse* pHouse = new CHouse;

	string name = "小红";
	pPeople->InitPeople(name, PEOPLE_MONEY);

	string cmd;
	showHelp();

	while (1)
	{
		//cin >> cmd;	// cmd只会读取到buy,空格后的内容没有读取到,可以尝试用getline解决该问题
		//getline(cin, cmd);	//第三个参数不给的话默认'\n'结束
		//问题:第二次循环到getline的时候,由于缓冲区有第一次cin没获取的\n,所以第二次getline时程序无法cin,直接获取缓冲区的\n,因此后面不会进入任何一个if,直接空循环一次再回到getline(此时为第三次,缓冲区为空,cin……,也就是说该代码在循环偶数次情况下均无法正常cin)
		//解决方式:利用cin.sync();//清除缓冲区
		cin.sync();
		getline(cin, cmd);
		
		//———————————————————————————— 退出————————————————————————————

		if (CMD_PROGRAM_QUIT == cmd)
		{
			break;
		}
		//——————————————————————————————————————————————————————————————

		//———————————————————————————— 帮助—————————————————————————————

		if (CMD_HELP == cmd)
		{
			showHelp();
		}
		//——————————————————————————————————————————————————————————————

		//—————————————————————人机交互 买动物 安置动物—————————————————————
		{
			CAnimal* pAni = NULL;
			string Animalname;
			string color;
			int age;

			if (CMD_BUY_ANIMAL_CAT == cmd)
			{
				cout << "买猫咪~" << endl;
				DEF_BUY_ANIMAL_PART(CCat, ANIMAL_KIDN_CAT);
			}
			else if (CMD_BUY_ANIMAL_DOG == cmd)
			{
				cout << "买狗狗~" << endl;
				DEF_BUY_ANIMAL_PART(CDog, ANIMAL_KIDN_DOG);
			}
			else if (CMD_BUY_ANIMAL_SNAKE == cmd)
			{
				cout << "买小蛇~" << endl;
				DEF_BUY_ANIMAL_PART(CSnake, ANIMAL_KIDN_SNAKE);
			}

			//安置动物

			if (pAni)//判断有没有动物,是否购买成功了
			{
				//建笼子
				CCage* pCage = pPeople->CreateCage();
				//装笼子
				pPeople->PushAnimal(pCage, pAni);
				//笼子放到房子里
				pPeople->PushCage(pHouse, pCage);
			}
		}
		//——————————————————————————————————————————————————————————————

		//——————————————————————————查看动物——————————————————————————————
		if (CMD_LOOK_ANIMAL == cmd) 
		{
			int id = 0;
			cout << "请输入查看笼子的ID(id==0:代表查看所有动物)" << endl;
			cin >> id;
			pPeople->LookAnimal(pHouse, id);
		}
		//——————————————————————————————————————————————————————————————

		int id = 0;

		//——————————————————————————杀死动物——————————————————————————————
		if (CMD_KILL_ANIMAL == cmd) 
		{
			cout << "请输入需要杀死动物的所属笼子ID" << endl;
			cin >> id;
			pPeople->KillAnimal(pHouse, id);
		}
		//——————————————————————————————————————————————————————————————

		//——————————————————————————销毁笼子————————————————————————————sshow
		if (CMD_DESTORY_CAGE == cmd)
		{
			cout << "请输入需要销毁的笼子ID" << endl;
			cin >> id;
			pPeople->DestoryCage(pHouse, id);
		}
		//——————————————————————————————————————————————————————————————

		//——————————————————————————和动物玩——————————————————————————————
		if (CMD_PLAYWITH_ANIMAL == cmd)
		{
			cout << "请输入想一起玩耍的动物所属笼子ID" << endl;
			cin >> id;
			pPeople->PlayWithAniamal(pHouse, id);
		}
		//——————————————————————————————————————————————————————————————

		//——————————————————————————人物信息——————————————————————————————
		if (CMD_SHOW_PEOPLE == cmd)
		{
			pPeople->ShowPeople();
		}
		//——————————————————————————————————————————————————————————————
	}

	//回收人、屋子的空间~(笼子和动物已经在屋子的析构里写了,所有不用再删啦)
	delete pPeople;
	pPeople = NULL;
	delete pHouse;
	pHouse = NULL;

	return 0;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
【资源说明】 基于C++开发的宠物小屋源码+项目说明+sln解决方案(课程设计).zip 基于C++开发的宠物小屋源码+项目说明+sln解决方案(课程设计).zip 基于C++开发的宠物小屋源码+项目说明+sln解决方案(课程设计).zip 1、该资源内项目代码都是经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能。 【需求分析】 需求分析: 动物猫(CCat)、狗(CDog)、蛇(CSnake),包含名字(m_strName)、颜色(m_strColor)、年龄(m_nAge)。 笼子类(CCage):它负责装3种动物,每个笼子编号不能相同。 房子类(CHouse):负责存放装动物的笼子。 人(CPeople):负责花钱买动物,造笼子,将动物放到笼子中,存放到房子里,杀死某个笼子动物,销毁某个笼子(如果有动物一并销毁), 查看某个或所有笼子动物,和某个动物玩耍。 控制台程序,通过输入命令,可以进行简单的人机交互。 提示:获取输入字符可以用 string::getline(cin, cmd); //获取输入的命令(阻塞等待) #include<string> basic_istream<_Elem, _Traits>& getline( basic_istream<_Elem, _Traits>& _Istr, basic_string<_Elem, _Traits, _Alloc>& _Str, const _Elem _Delim) _Istr :表示一个输入流,譬如cin. _Str :将输入流读取的字符串放到_Str 中。 _Delim:遇到这个字符就停止读取,不设置默认为'\n' 本项目是作者初学C++中类相关知识的时候写的一个练习使用类的小项目。 > - 类之间的横向关系和纵向关系是C++中很重要的一部分知识点,初学C++者通过练习这个项目可以加深对C++中类之间关系的理解,可以对理论上的相关概念加以实践练习,对学习C++很有帮助。 > - 如发现源代码中有错误或者有其它问题,欢迎大家在 `Issues` 中研究讨论,欢迎大家 `Fork` 和 `Pull requests` 改善代码,十分感谢! ## 使用语言 - C++ ## 主要技术 * **类的使用练习** ## 项目整体思路 - 文件中有项目的需求分析文档,还有项目的类图分析文档,通过这些很容易上手练习这个小项目。 - 项目中使用的是通过控制台输入命令来简单交互的,感兴趣的可以加上图形用户界面。 ## 运行 - 使用 Visual Studio 打开项目中的.sln文件,编译运行即可。 - 作者之前使用的VS2012是可以正常运行的,不同的版本可能会有一点点小问题,但都很容易解决。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

97Marcus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值