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!