HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Temperature Converter With Modern C++

Submitted by: @import:stackexchange-codereview··
0
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

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.

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);}
 ... etc


The 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);}
 ... etc

Context

StackExchange Code Review Q#105261, answer score: 3

Revisions (0)

No revisions yet.