patterncppMinor
Temperature Converter With Modern C++
Viewed 0 times
withtemperatureconvertermodern
Problem
Inspired by an earlier question I've made a temperature converter that can convert from one temperature to another and optionally output a series of conversions.
This was made in Visual Studio 2015 but it also compiles with g++ and clang++ on Debian with no warnings.
Usage
or
Where the arguments are:
stdafx.h
Temperature.h
`#pragma once
#include "stdafx.h"
namespace hest {
enum class TemperatureUnit
{
Invalid,
Celcius,
Fahrenheit,
Kelvin,
Rankine,
};
class TemperatureData;
class Kelvin;
class Temperature {
public:
typedef std::unique_ptr UniqueTemperature;
static std::string ToShortString(TemperatureUnit const unit);
static std::string ToString(TemperatureUnit const unit);
static TemperatureUnit StringToUnit(std::string const & unit);
static TemperatureUnit CharToUnit(char unit);
static UniqueTemperature CreateTemperature(double degrees, TemperatureUnit unit);
static UniqueTemperature Convert(Temperature const & from, TemperatureUnit const to);
double degrees() const;
TemperatureUnit unit() const;
std::string ToString() const;
virtual Kelvin ToKelvin() const = 0;
protected:
Temperature(double degrees, TemperatureUnit unit);
private:
std::shared_ptr data_;
};
class Kelvin final : public Temperature {
public:
Kelvin(double degrees);
This was made in Visual Studio 2015 but it also compiles with g++ and clang++ on Debian with no warnings.
Usage
tc.exe -40 c f
Celcius | Fahrenheit
------------------+------------------
-40.00 | -40.00
or
tc.exe -40 c f 10 10
Celcius | Fahrenheit
------------------+------------------
-40.00 | -40.00
-30.00 | -22.00
-20.00 | -4.00
-10.00 | 14.00
0.00 | 32.00
10.00 | 50.00
Where the arguments are:
Usage: tc.exe Degrees InitialUnit ConvertedUnit [InitialUnitStepSize InitialUnitUpperBoundInclusive]
stdafx.h
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
Temperature.h
`#pragma once
#include "stdafx.h"
namespace hest {
enum class TemperatureUnit
{
Invalid,
Celcius,
Fahrenheit,
Kelvin,
Rankine,
};
class TemperatureData;
class Kelvin;
class Temperature {
public:
typedef std::unique_ptr UniqueTemperature;
static std::string ToShortString(TemperatureUnit const unit);
static std::string ToString(TemperatureUnit const unit);
static TemperatureUnit StringToUnit(std::string const & unit);
static TemperatureUnit CharToUnit(char unit);
static UniqueTemperature CreateTemperature(double degrees, TemperatureUnit unit);
static UniqueTemperature Convert(Temperature const & from, TemperatureUnit const to);
double degrees() const;
TemperatureUnit unit() const;
std::string ToString() const;
virtual Kelvin ToKelvin() const = 0;
protected:
Temperature(double degrees, TemperatureUnit unit);
private:
std::shared_ptr data_;
};
class Kelvin final : public Temperature {
public:
Kelvin(double degrees);
Solution
I don't think I would have used a class hierarchy to represent the different types of temperature. In the end they represent the same thing (the amount of energy in a system). You should pick a unit to store that data in then covert all types to this global unit.
Then write
The cost of passing an object of type
class Temperature
{
double kelvin;
public:
// Explicit: We don't want auto-conversion.
explicit Temperature(double kelvin)
: kelvin(kelvin)
{}
};Then write
make_temp_from_X() functions that convert a particular scale to your chosen form.Temperature make_temp_from_kelvin(double k) {return Temperature(k);}
Temperature make_temp_from_celcius{double c) {return Temperature(c-273.15);}
... etcThe cost of passing an object of type
Temperature around is the same cost as passing a double around (so you don't really need to worry about that).Code Snippets
class Temperature
{
double kelvin;
public:
// Explicit: We don't want auto-conversion.
explicit Temperature(double kelvin)
: kelvin(kelvin)
{}
};Temperature make_temp_from_kelvin(double k) {return Temperature(k);}
Temperature make_temp_from_celcius{double c) {return Temperature(c-273.15);}
... etcContext
StackExchange Code Review Q#105261, answer score: 3
Revisions (0)
No revisions yet.