OOP Step One Project
Farm Animals Example
Aniaml Header (Animal.h)
#ifndef ANIMAL_H
#define ANIMAL_H
class CAnimal
{
private:
int mAnimalType = 0;
public:
virtual ~CAnimal();
/** Display an animal. */
virtual void DisplayAnimal() {}
/** Keep track of the number of witch weight animals. */
virtual void IsWitchWeight() {}
/**Setter and getter for type of animal for the purpose of witch weight. */
void setDuckType(int duckType) { mAnimalType = duckType; }
int getDuckType() { return mAnimalType; }
};
#endif
Animal Functions (Animal.cpp)
#include "Animal.h"
/**
* Destructor
*/
CAnimal::~CAnimal(){}
Chicken Header (Chicken.h)
#ifndef CHICKEN_H
#define CHICKEN_H
#include <string>
#include "Animal.h"
// Declaration of the CChicken class.
/** Class that describes a chicken.
*/
class CChicken : public CAnimal
{
private:
//! The chicken's ID
std::string mId;
public:
void ObtainChickenInformation();
void DisplayAnimal();
};
#endif
Chicken Functions (Chicken.cpp)
#include <iostream>
#include "Chicken.h"
/** Obtain a chicken description from the user.
*/
void CChicken::ObtainChickenInformation()
{
std::cout << endl;
std::cout << "Input information about the chicken" << std::endl;
// Obtain the ID. This is easy, since it's just a
// string.
std::cout << "Id: ";
std::cin >> mId;
}
/** Display the chicken.
*/
void CChicken::DisplayAnimal()
{
std::cout << "Chicken: " << mId << std::endl;
}
Cow Header (Cow.h)
#ifndef COW_H
#define COW_H
#include <string>
#include "Animal.h"
/**
* Class that describes a cow.\
*
* Holds a collection of cows that make up the cow inventory.
*/
class CCow : public CAnimal
{
private:
/// The cow's name
std::string mName;
/// The type of cow: Bull, BeefCow, or MilkCow
Type mType = Type::MilkCow;
/// The milk production for a cow in gallons per day
double mMilkProduction = 0;
public:
/// The types of cow we can have on our farm
enum class Type { Bull, BeefCow, MilkCow };
void ObtainCowInformation();
void DisplayAnimal();
};
#endif
Cow Functions (Cow.cpp)
#include <iostream>
#include "Cow.h"
// #include "leak.h"
using std::cout;
using std::end;
using std::cin;
/**
* Obtain information from the user about this cow.
*
* Asks the user for the information that describes a cow.
*/
void CCow::ObtainCowInformation()
{
cout << endl;
cout << "Input information about the cow" << endl;
// Obtain the name. This is easy, since it's just a
// string.
cout << "Name: ";
cin >> mName;
// Obtain the type using a menu. We have a loop so
// we can handle errors.
bool valid = false;
while (!valid)
{
cout << "1: Bull" << endl;
cout << "2: Beef Cow" << endl;
cout << "3: Milk Cow" << endl;
cout << "Enter selection and return: " << endl;
int option;
cin >> option;
if (!cin)
{
// We have an error. Clear the input and try again
cin.clear();
cin.ignore();
continue;
}
switch (option)
{
case 1:
mType = Type::Bull;
valid = true;
break;
case 2:
mType = Type::BeefCow;
valid = true;
break;
case 3:
mType = Type::MilkCow;
valid = true;
break;
}
}
if (mType == Type::MilkCow)
{
valid = false;
while (!valid)
{
cout << "Enter milk production in gallons per day: ";
cin.clear();
cin.ignore();
cin >> mMilkProduction;
if (cin)
{
valid = true;
}
}
}
else
{
// If not a milk cow, we have no milk production
mMilkProduction = 0;
}
}
/**
* Display information about this cow.
*/
void CCow::DisplayAnimal()
{
cout << mName << ": ";
switch (mType)
{
case Type::Bull:
cout << "Bull" << endl;
break;
case Type::BeefCow:
cout << "Beef Cow" << endl;
break;
case Type::MilkCow:
cout << "Milk Cow/" << mMilkProduction << " GPD" << endl;
break;
}
}
Duck Header (Duck.h)
#ifndef DUCK_H
#define DUCK_H
#include <string>
#include "Animal.h"
#include "Farm.h"
using std::string;
/**
* Class that describes a duck.\
*
* Holds a collection of ducks that make up the cow inventory.
*/
class CDuck : public CAnimal
{
private:
/// Duck's name
string mName;
/// The type of duck, with default being the Disney duck
Type mType = Type::Disney;
public:
/// The types of duck we can have on our farm
enum class Type { Mallard, Wood, Disney, WarnerBrothers };
void ObtainDuckInformation();
void DisplayAnimal();
/** Sets type of animal to check for witch weight. */
void setType() { CAnimal::setDuckType(int(mType)); }
};
#endif
Duck Functions (Duck.cpp)
#include <iostream>
#include "Duck.h"
// #include "leak.h"
using std::cout;
using std::cin;
using std::endl;
/**
* Obtain information from the user about this duck.
*
* Asks the user for the information that describes a duck.
*/
void CDuck::ObtainDuckInformation()
{
cout << endl;
cout << "Input duck's name: " << endl;
cin.ignore();
getline(cin, mName);
while (mName.empty() || mName[0] == ' ')
{
cout << "Invalid name, re-eneter a valid name: " << endl;
//cin.ignore();
getline(cin, mName);
}
CFarm farm;
bool valid = false;
while (!valid)
{
cout << "1: Mallard Duck" << endl;
cout << "2: Wood Duck" << endl;
cout << "3: Disney Duck" << endl;
cout << "4: Warner Brothers Duck" << endl;
cout << "Enter selection and return: " << endl;
int option;
cin >> option;
if (!cin)
{
// We have an error. Clear the input and try again
cin.clear();
cin.ignore();
continue;
}
switch (option)
{
case 1:
mType = Type::Mallard;
setType();
valid = true;
break;
case 2:
mType = Type::Wood;
setType();
valid = true;
break;
case 3:
mType = Type::Disney;
setType();
valid = true;
break;
case 4:
mType = Type::WarnerBrothers;
setType();
valid = true;
break;
}
}
}
/**
* Display information about this duck.
*/
void CDuck::DisplayAnimal()
{
cout << mName << ": ";
switch (mType)
{
case Type::Mallard:
cout << "Mallard Duck" << endl;
break;
case Type::Wood:
cout << "Wood Duck" << endl;
break;
case Type::Disney:
cout << "Disney Duck" << endl;
break;
case Type::WarnerBrothers:
cout << "Warner Brothers Duck" << endl;
break;
}
}
Farm Header (Farm.h)
#ifndef FARM_H
#define FARM_H
#include <vector>
#include <string>
#include "Cow.h"
#include "Duck.h"
using std::string;
/**
* Class that describes a farm.
*
* Holds a collection of animals that make up the farm
* inventory.
*/
class CFarm
{
public:
~CFarm();
void AddAnimal(CAnimal* animal);
void DisplayInventory();
void IsWitchWeight(CAnimal* animal);
void DisplayWitchWeight();
private:
/// A list with the inventory of all animals on the farm
std::vector<CAnimal*> mInventory;
/// Duck's type
string mDuckTypeName;
/// Counter for witch weight animals in the farm
int mWitchWeight = 0;
};
#endif
Farm Functions (Farm.cpp)
#include <typeinfo>
#include <iostream>
#include <string>
#include "Farm.h"
// #include "leak.h"
using std::cout;
using std::cin;
using std::endl;
/**
* CFarm destructor
*/
CFarm::~CFarm()
{
// Iterate over all of the animals, destroying
// each one.
for (auto animal : mInventory)
{
delete animal;
}
// And clear the list
mInventory.clear();
// Reset the witch weight count to 0
mWitchWeight = 0;
}
/** Add an animal to the farm inventory.
*
* Also increments count of witch weight animals.
*
* \param animal: An animal to add to the inventory
*/
void CFarm::AddAnimal(CAnimal* animal)
{
mInventory.push_back(animal);
if (animal->getDuckType() != 2)
{
IsWitchWeight(animal);
}
}
/**
* Display the farm inventory.
*/
void CFarm::DisplayInventory()
{
for (auto animal : mInventory)
{
animal->DisplayAnimal();
}
}
/**
* Increments the number of witch weight animals.
*/
void CFarm::IsWitchWeight(CAnimal* animal)
{
++mWitchWeight;
}
/**
* Displays the number of witch weight animals.
*/
void CFarm::DisplayWitchWeight()
{
cout << "There are " << mWitchWeight << " witch-weight animals." << endl;
}
Main File (main.cpp)
#include <iostream>
#include "Farm.h"
#include "Cow.h"
#include "Chicken.h"
#include "Duck.h"
// #include "leak.h"
using std::cout;
using std::cin;
using std::endl;
/**
* Main entry point.
*
* This is where the program starts.
* \return 0
*/
int main()
{
// Support memory leak detection
// _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
cout << "Instantiating Farm" << endl;
CFarm farm;
// This loops continuously until we are done
bool done = false;
while (!done)
{
// Output user instructions
cout << endl;
cout << "Farm management" << endl;
cout << "1 - Add cow" << endl;
cout << "2 - Add chicken" << endl;
cout << "3 - Add duck" << endl;
cout << "9 - List inventory" << endl;
cout << "11 - Number of witch-weight animals" << endl;
cout << "99 - Exit" << endl;
cout << "Select Option: ";
// Get option from the user
int option;
cin >> option;
// Handle invalid input
if (!cin)
{
option = 1000;
cin.clear();
cin.ignore(); // Discard bad input
}
// Handle the possible user options
switch (option)
{
case 1:
{
cout << "Adding cow" << endl;
CCow* cow = new CCow();
cow->ObtainCowInformation();
farm.AddAnimal(cow);
}
break;
case 2:
{
cout << "Adding chicken" << endl;
CChicken* chicken = new CChicken();
chicken->ObtainChickenInformation();
farm.AddAnimal(chicken);
}
break;
case 3:
{
cout << "Adding duck" << endl;
CDuck* duck = new CDuck();
duck->ObtainDuckInformation();
farm.AddAnimal(duck);
}
break;
case 9:
farm.DisplayInventory();
break;
case 11:
farm.DisplayWitchWeight();
break;
case 99:
done = true;
break;
default:
cout << "Invalid option" << endl;
break;
}
}
return 0;
}
DONE!