Hi everyone.
I am trying to develop a class for a RISK boardgame, and I used UNIT_COLOR and UNIT_TYPE enums to represent the different types of pieces. These enumerations are defined as public in my class but are causing complete havoc in my code because with the C++11 "class enum," I need to start accessing my enumerations through the enum class name. However, if the enumeration is in the class itself, then I will need to access a data member from enumeration in the following way: ClassName::EnumClassName::theEnum
.
This is causing havoc on my code as my compiler does not recognize that I have the same function definitions both in my header file and in the .cpp file implementation.
Let me show you what I mean:
// Class definition of a UNIT
#ifndef Unit_hpp
#define Unit_hpp
#include <map>
#include <iostream>
//forward declaration of class to prevent header file import statement mixup
class Territory;
///////////////////////////////////////////////////////////////////////////////
//represents each type of unit that can be created and the number of "single units" in each troop, correspondingly"
//creating forward declarations of enumerations
enum class UNIT_COLOR; enum class UNIT_TYPE; enum class UNIT_COLOR;
///////////////////////////////////////////////////////////////////////////////
class Unit
{
public:
Unit(Territory*,UNIT_TYPE&,UNIT_COLOR&);
~Unit(); //destructor
void move(Territory*); //moves the UNIT to a new Territory
void setAlive(const bool&); //makes the unit alive or dead, respectively
bool isAlive() const; //returns true if the unit is alive
const UNIT_COLOR getColor() const; //returns the UNIT's color
void setColor(UNIT_COLOR&);
const UNIT_TYPE getUnitType() const;
void setUnitType(UNIT_TYPE&);
int getUnitStrength() const;
///////////////////////////////////////////////////////////////////////////////////
//used for displaying a Unit's state
friend std::ostream& operator << (std::ostream&,const Unit&);
//these represent the possible colors that a RISK unit may have
enum class UNIT_COLOR {YELLOW, BLUE, RED, GREEN, GREY};
//represents the type of Risk unit
enum class UNIT_TYPE { INFANTRY, CAVALRY, CANNON };
static const std::map<UNIT_TYPE,int> UNIT_TO_UNIT_STRENGTH;
private:
Territory* currentTerritoryPtr;
int numTroops;
UNIT_TYPE typeUnit;
bool living; //represents if the unit is "living". i.e. if it can be manipulated
UNIT_COLOR color;
static const int MOBILITY = 1; //number of territories that a unit can move through on a single turn
};
//initializing the static map
const std::map<Unit::UNIT_TYPE,int> Unit::UNIT_TO_UNIT_STRENGTH =
{
{Unit::UNIT_TYPE::INFANTRY,1}, {Unit::UNIT_TYPE::CAVALRY,3}, {Unit::UNIT_TYPE::CANNON,5}
};
#endif /* Unit_hpp */
and then my .cpp implementation file is:
// Defines the member functions of the Unit class
#include "Unit.hpp"
//used for displaying a Unit's state
std::ostream& operator << (std::ostream& os,const Unit& theUnit)
{
switch (theUnit.color)
{
case Unit::UNIT_COLOR::YELLOW:
os << "Yellow";
break;
case Unit::UNIT_COLOR::BLUE:
os << "Blue";
break;
case Unit::UNIT_COLOR::RED:
os << "Red";
break;
case Unit::UNIT_COLOR::GREEN:
os << "Green";
break;
case Unit::UNIT_COLOR::GREY:
os << "Grey";
break;
default:
os << "Unknown-colored";
break;
}
os << " ";
switch(theUnit.typeUnit)
{
case Unit::UNIT_TYPE::INFANTRY:
os << "infantry unit";
break;
case Unit::UNIT_TYPE::CAVALRY:
os << "cavalry unit";
break;
case Unit::UNIT_TYPE::CANNON:
os << "cannon unit";
break;
default:
os << "unit";
break;
}
os << " in " << (theUnit.currentTerritoryPtr)->getName();
if (theUnit.living)
//the unit is alive
os << " that is alive." << std::endl;
else
//the unit is not alive
os << " that is dead." << std::endl;
return os;
}
/*
Unit::Unit(Territory* tPtr,const UNIT_TYPE& type,const UNIT_COLOR& c): currentTerritoryPtr(tPtr),typeUnit(type), color(c)
{
living = true; //by default, the unit is alive at the time of creation
numTroops = UNIT_TO_UNIT_STRENGTH.find(typeUnit)->second;
}*/
Unit::Unit(Territory* tPtr,UNIT_TYPE& type,UNIT_COLOR& c): currentTerritoryPtr(tPtr),typeUnit(type),color(c)
{
living = true; //by default, the unit is alive at the time of creation
numTroops = UNIT_TO_UNIT_STRENGTH.find(typeUnit)->second;
}
Unit::~Unit()
{
currentTerritoryPtr = nullptr; //trying to prevent memory leak
}
void Unit::move(Territory* destinationPtr)
{
//have the current territory delete the unit's reference to the unit
currentTerritoryPtr->removeUnit(this);
//represents the unit moving from a current territory
//to the destination. assuming that the destination
//reference by the destinationPtr has been vetted.
currentTerritoryPtr = destinationPtr;
//then have the new territory accept the unit
currentTerritoryPtr->takeInUnit(this);
}
void Unit::setAlive(const bool& newState)
{
living = newState;
}
bool Unit::isAlive() const
{
return living;
}
const Unit::UNIT_COLOR Unit::getColor() const
{
return color;
}
void Unit::setColor(UNIT_COLOR& newC)
{
color = newC;
}
const UNIT_TYPE Unit::getUnitType() const
{
return typeUnit;
}
void Unit::setUnitType(UNIT_TYPE& newType)
{
typeUnit = newType;
numTroops = UNIT_TO_UNIT_STRENGTH.find(typeUnit)->second;
}
int Unit::getUnitStrength() const
{
return numTroops;
}
And then I get the following errors for my .cpp file implementation (keep in mind that this is on xCode which guides me through formatting my code as well, and xCode was happy with my header file):
For the constructor "Out of line definition of 'Unit' does not match any declaration in 'Unit'
*For the member function getColor(), it returns "Return type of out-of-line definition of Unit::getColor differs from that in the declaration.OK. Fine. I just went to the header file and changed my return type for getColor() from UNIT_COLOR to Unit::UNIT_COLOR to match what was in the .cpp file. However, xCode prompted me to delete the "Unit::"" and to just keep the return type "UNIT_COLOR," so I do not know how to fix this issue.
- For setColor, "Out of line definition of setColor does not match any declaration in 'Unit'
A few other functions also have an error similar to that of setColor including setUnitType and getUnitType(). something in these enums is causing me havoc.
I have been pouring over this for many hours. I was wondering if any of you programmers would have an insight or see something instantly that I am not seeing and then care to weigh in.
Thank you very much for your help in advance.