2012-07-19 12 views
5

Estoy tratando de crear unidades para metro y kilómetro. Quiero sumarlos y convertirlos en consecuencia. Sé que la biblioteca boost :: units ya tiene el sistema SI, pero quiero crear todo desde cero, porque entonces tengo que crear mis propios sistemas para mis proyectos (así que estoy haciendo esto para aprender). Mi propósito es declarar una variable "longitud" que puede ser modificado usando unidades: por ejemplo, quiero escribirCreando conversiones definidas por el usuario

Length xLength1 = 5350 * Meters + 2 Kilometers; 

Para ello, he creado el archivo length.h, que contiene las definiciones de metros y kilómetros, y al final declaro la conversión entre estas dos unidades:

#ifndef LENGTH_H_ 
#define LENGTH_H_ 

#include <boost/units/base_dimension.hpp> 
#include <boost/units/base_unit.hpp> 
#include <boost/units/scaled_base_unit.hpp> 
#include <boost/units/quantity.hpp> 
#include <boost/units/conversion.hpp> 

struct LengthBaseDimension : boost::units::base_dimension<LengthBaseDimension,1>{}; 

typedef LengthBaseDimension::dimension_type LengthDimension; 

struct MeterBaseUnit : boost::units::base_unit<MeterBaseUnit, LengthDimension, 1>{}; 
template <> struct boost::units::base_unit_info<MeterBaseUnit> 
{ 
    static std::string name() { return "meter"; } 
    static std::string symbol() { return "m";  } 
}; 

struct KilometerBaseUnit : boost::units::base_unit<KilometerBaseUnit, LengthDimension, 2>{}; 
template <> struct boost::units::base_unit_info<KilometerBaseUnit> 
{ 
    static std::string name() { return "kilometer"; } 
    static std::string symbol() { return "km";  } 
}; 

// I don't want to use scaled_unit because I need this for my real purpose 
BOOST_UNITS_DEFINE_CONVERSION_FACTOR(KilometerBaseUnit, MeterBaseUnit, double, 1000.0); 

#endif 

Luego de crear el archivo en el que units.h defino mi propio sistema de unidades

#ifndef LIB_UNITS_H_ 
#define LIB_UNITS_H_ 

#include "length.h" 
#include <boost/units/unit.hpp> 
#include <boost/units/static_constant.hpp> 
#include <boost/units/make_system.hpp> 
#include <boost/units/io.hpp> 

typedef boost::units::make_system<MeterBaseUnit>::type UnitsSystem; 

typedef boost::units::unit<boost::units::dimensionless_type, UnitsSystem> Dimensionless; 
typedef boost::units::unit<LengthDimension     , UnitsSystem> SystemLength; 


BOOST_UNITS_STATIC_CONSTANT(Kilometer , SystemLength); 
BOOST_UNITS_STATIC_CONSTANT(Kilometers , SystemLength); 
BOOST_UNITS_STATIC_CONSTANT(Meter  , SystemLength); 
BOOST_UNITS_STATIC_CONSTANT(Meters  , SystemLength); 

// Typedefs of dimensions 
typedef boost::units::quantity<SystemLength> Length; 

#endif 

Al menos, yo uso esta cabecera en mi función principal

#include "units.h" 
#include <iostream> 

int main(void) 
{ 
    Length xLength1 (300.0 * Meters); 
    Length xLength2 (1500.0 * Kilometer); 
    Length xLength3; 
    std::cout << xLength2 << std::endl; 
    xLength3 = xLength1 + xLength2; 

    return 0; 
} 

Este proyecto compila, pero no hace lo que yo quiero. Cuando imprimo la variable xLength2, obtengo 1500 m en lugar de 1500 km o 1500000 m. La suma también es incorrecta, porque yo trabajoin 1800 m. Es como considerar kilómetros como metros y la conversión no funciona.

¿Qué estoy haciendo mal?

+0

Usted define 'Kilometer' para que sea igual que' Meter'. No recuerdo de improviso cuál es la forma preferida de definir 'Kilómetro' (quizás hay una macro diferente), pero puedes probar algo como 'const Length Kilometer = 1000 * Meters;' (mezclando el orden de las definiciones). –

+1

Pero en este caso no puedo escribir y tomar valor en kilómetros, pero solo en metros. Quiero la posibilidad de trabajar con ambas unidades, y usar ambos valores donde sea necesario. – Jepessen

+0

Solo un aviso, si está usando MSVC++ o el gcc, puede reemplazar sus guardias '#IFDEF LENGTH_H_' etc. con' #pragma una vez' en la parte superior de cada encabezado. –

Respuesta

0

A menos que su proyecto sea replicar la biblioteca de Boost, esto parece una manera loca de codificar un sistema de unidad. La piratería de plantillas rara vez es la mejor opción.

En su lugar, use una clase! Código no real a continuación:

class temperature{ 
    double temp; //always in kelvin 
    temperature(double temperature, char unit){ 
     if(unit=='k') 
       temp=temperature 
     if(unit=='c') 
       temp=temperature+273 
    } 
}; 

Y así sucesivamente para implementar la conversión a la unidad que desee. Básicamente, eliges una unidad base en la que todo está almacenado, y la conviertes a partir de eso. Si está haciendo SI, quizás gramos, metros, segundos, Kelvin, etc.

+0

Esto no es forma Boost.Units, por lo tanto, no responde la pregunta. – Ruslan

Cuestiones relacionadas