I am trying to practice OO design. I’ve made the following classes, which will eventually let a user pick a temperature unit type (like fahrenheit) from a list, and convert celcius temperatures to their chosen temperature:
TemperatureUnits.h:
#include "fahrenheittemperatureunit.h"
#include "kelvintemperatureunit.h"
#include "temperatureunit.h"
#include <list>
class TemperatureUnits
{
public:
static std::list<TemperatureUnit> All();
const static FahrenheitTemperatureUnit kFahrenheit;
const static KelvinTemperatureUnit kKelvin;
};
TemperatureUnits.cpp:
#include "temperatureunits.h"
std::list<TemperatureUnit> TemperatureUnits::All()
{
std::list<TemperatureUnit> units;
units.push_back(TemperatureUnits::kFahrenheit);
units.push_back(TemperatureUnits::kKelvin);
return units;
}
const KelvinTemperatureUnit TemperatureUnits::kKelvin;
const FahrenheitTemperatureUnit TemperatureUnits::kFahrenheit;
TemperatureUnit.h
class TemperatureUnit
{
public:
explicit TemperatureUnit(const std::string &name);
virtual ~TemperatureUnit() {}
const std::string& Name() const;
virtual float FromCelcius(float celcius) const {return 0;}
private:
std::string name_;
};
TemperatureUnit.cpp:
#include "temperatureunit.h"
TemperatureUnit::TemperatureUnit(const std::string &name)
:
name_(name)
{
}
const std::string& TemperatureUnit::Name() const
{
return name_;
}
Lastly, an example subclass:
KelvinTemperatureUnit.h:
#include "temperatureunit.h"
class KelvinTemperatureUnit : public TemperatureUnit
{
public:
explicit KelvinTemperatureUnit();
virtual float FromCelcius(float celcius) const;
};
KelvinTemperatureUnit.cpp:
#include "kelvintemperatureunit.h"
KelvinTemperatureUnit::KelvinTemperatureUnit()
:
TemperatureUnit(std::string("Kelvin"))
{
}
float KelvinTemperatureUnit::FromCelcius(float celcius) const
{
return celcius - 273;
}
There are a number of flaws (that I know of) in the above:
-
I’m not sure the
class TemperatureUnits{ ... static std::list<TemperatureUnit> All();pattern is the correct one to use, but unsure what would actually be better. -
By storing the types of TemperatureUnit in a std::list, they are treated as the base class TemperatureUnit, instead of their specialisations like KelvinTemperatureUnit. This means calling the FromCelcius method doesn’t work correctly. I am pretty sure I used to do this type of thing using Java.
-
I had a go, but it is probably pretty ugly and will offend someone 🙁
Does anyone have any ideas on the best way to go about this?
thanks!
Java objects are references. C++ objects are values. Simply convert to a reference, and then you will have more equivalent code. Oh, and a Java
listis a C++vector. A C++listis a linked list.Quite simply, do not bother to carry over any Java knowledge to C++, they are extremely different languages, you should start with C++ from scratch. C++ worth writing looks extremely different to Java.