Code:
#include <iostream>
#include <string>
#include <list>
// RESEARCH CLASS
class ResearchBase
{
public:
ResearchBase(const std::string& researchName,
bool thisResearchCompleted,
unsigned int daysToCompleteThis);
virtual ~ResearchBase();
bool ResearchCompleted() const;
int DaysToComplete() const;
void Output(std::ostream& out, unsigned int indent = 0) const;
void AddChild(ResearchBase* researchBase);
protected:
ResearchBase* GetFirstChild() const;
ResearchBase* GetNextChild() const;
private:
void ClearChildren();
std::string researchName_;
bool thisResearchCompleted_;
unsigned int daysToCompleteThis_;
typedef std::list<ResearchBase*> ChildPointerList;
ChildPointerList m_listChildren;
// declare after the list for proper initialization
mutable ChildPointerList::const_iterator m_iterChild;
};
ResearchBase::ResearchBase(const std::string& researchName,
bool thisResearchCompleted,
unsigned int daysToCompleteThis)
: researchName_(researchName),
thisResearchCompleted_(thisResearchCompleted),
daysToCompleteThis_(daysToCompleteThis),
m_iterChild(m_listChildren.end())
{
}
ResearchBase::~ResearchBase()
{
ClearChildren();
}
bool ResearchBase::ResearchCompleted() const
{
ResearchBase* childResearch = GetFirstChild();
while (childResearch)
{
if (!childResearch->ResearchCompleted())
return false;
childResearch = GetNextChild();
}
return thisResearchCompleted_;
}
int ResearchBase::DaysToComplete() const
{
unsigned int days = daysToCompleteThis_;
ResearchBase* childResearch = GetFirstChild();
while (childResearch)
{
days += childResearch->DaysToComplete();
childResearch = GetNextChild();
}
return days;
}
void ResearchBase::Output(std::ostream& out, unsigned int indent/* = 0*/) const
{
if (indent != 0)
out << std::string(indent, ' ');
out << researchName_ << ": Days To Complete: " << DaysToComplete() << " -- ";
if (ResearchCompleted())
out << "COMPLETED";
else
out << "INCOMPLETE";
out << std::endl;
ResearchBase* childResearch = GetFirstChild();
while (childResearch)
{
childResearch->Output(out, indent + 2);
childResearch = GetNextChild();
}
}
void ResearchBase::AddChild(ResearchBase* researchBase)
{
m_listChildren.push_back(researchBase);
}
ResearchBase* ResearchBase::GetFirstChild() const
{
m_iterChild = m_listChildren.begin();
if (m_iterChild != m_listChildren.end())
return *m_iterChild;
return 0;
}
ResearchBase* ResearchBase::GetNextChild() const
{
if (m_iterChild == m_listChildren.end())
return 0;
if ((++m_iterChild) != m_listChildren.end())
return *m_iterChild;
return 0;
}
void ResearchBase::ClearChildren()
{
m_iterChild = m_listChildren.begin();
ChildPointerList::const_iterator iterEnd = m_listChildren.end();
for (; m_iterChild != iterEnd; ++m_iterChild)
delete (*m_iterChild);
m_listChildren.clear();
m_iterChild = m_listChildren.end();
}
// CREATION
int main()
{
std::auto_ptr<ResearchBase> rootResearch(new ResearchBase("RESEARCH", true, 0));
ResearchBase* researchAgStudies =
new ResearchBase("Agricultural Studies", true, 0);
rootResearch->AddChild(researchAgStudies);
ResearchBase* researchHydropGrMedia =
new ResearchBase("Hydroponic Growing Media", false, 30);
researchAgStudies->AddChild(researchHydropGrMedia);
ResearchBase* researchExpHydrop =
new ResearchBase("Expanded Hydroponics", false, 2);
researchAgStudies->AddChild(researchExpHydrop);
ResearchBase* researchLScCndsCircuit =
new ResearchBase("Large Scale Condenser Circuit", true, 2);
researchExpHydrop->AddChild(researchLScCndsCircuit);
ResearchBase* researchGenFoodEng =
new ResearchBase("Genetic Food Engineering", true, 0);
researchExpHydrop->AddChild(researchGenFoodEng);
ResearchBase* researchAdvGenetics =
new ResearchBase("Advanced Genetics", true, 3);
researchGenFoodEng->AddChild(researchAdvGenetics);
ResearchBase* researchArtFlavoring =
new ResearchBase("Artificial Flavoring", true, 5);
researchGenFoodEng->AddChild(researchArtFlavoring);
ResearchBase* researchFoodSynth =
new ResearchBase("Food Synthesis", true, 0);
researchGenFoodEng->AddChild(researchFoodSynth);
ResearchBase* researchGeoStudies =
new ResearchBase("Geographical Studies", true, 0);
rootResearch->AddChild(researchGeoStudies);
ResearchBase* researchGenGeology =
new ResearchBase("General Geology", true, 0);
researchGeoStudies->AddChild(researchGenGeology);
ResearchBase* researchSeismology =
new ResearchBase("Seismology", true, 10);
researchGenGeology->AddChild(researchSeismology);
ResearchBase* researchStrShockResHousing =
new ResearchBase("Structural Shock-Resistant Housing", true, 8);
researchSeismology->AddChild(researchStrShockResHousing);
ResearchBase* researchVulcanology =
new ResearchBase("Vulcanology", true, 3);
researchGenGeology->AddChild(researchVulcanology);
ResearchBase* researchLavaDivWalls =
new ResearchBase("Lava Diversion Walls", false, 5);
researchVulcanology->AddChild(researchLavaDivWalls);
ResearchBase* researchVolcActPreWarning =
new ResearchBase("Volcanic Activity Pre-Warning", false, 5);
researchVulcanology->AddChild(researchVolcActPreWarning);
ResearchBase* researchLavaMinDeposits =
new ResearchBase("Lava-Based Mineral Deposits", true, 1);
researchVulcanology->AddChild(researchLavaMinDeposits);
rootResearch->Output(std::cout);
}