2012-07-19 5 views
5

Sto provando a creare unità per metri e chilometri. Voglio quindi sommarli e convertirli di conseguenza. So che la libreria boost :: units ha già il sistema SI, ma voglio creare tutto da zero, perché poi ho bisogno di creare i miei sistemi per i miei progetti (quindi lo sto facendo per imparare). Il mio scopo è quello di dichiarare una variabile "Lunghezza" che può essere modificata utilizzando unità: per esempio io voglio scrivereCreazione di conversioni definite dall'utente

Length xLength1 = 5350 * Meters + 2 Kilometers; 

A tal fine, ho creato il file dilength.h, contenente definizioni di metro e chilometri, e alla fine dichiaro la conversione tra queste due unità:

#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 

Poi ho creato il file in cui units.h definisco il mio sistema di unità

01.235.164,106174 millions
#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 

Almeno, io uso questa intestazione nella mia funzione principale

#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; 
} 

Questo progetto compila, ma non fa quello che voglio. Quando stampo la variabile xLength2, ottengo 1500 m anziché 1500 km o 1500000 m. La somma è anche sbagliata, perché mi astengo da 1800 m. È come se considerassi i chilometri come metri e la conversione non funziona.

Cosa sto facendo male?

+0

Si definisce 'Chilometro' come uguale a' Metro'. Non ricordo in anticipo quale sia il modo preferito per definire 'Chilometro '(forse c'è una diversa macro), ma puoi provare qualcosa come' const Lunghezza Chilometraggio = 1000 * Metri; '(mischiando l'ordine delle definizioni). –

+1

Ma in questo caso non posso scrivere e prendere valore in chilometri, ma solo in metri. Voglio la possibilità di lavorare con entrambe le unità e utilizzare entrambi i valori dove necessario. – Jepessen

+0

Solo un avviso, se stai usando MSVC++ o gcc, puoi sostituire le tue guardie #IFDEF LENGTH_H_' etc con '#pragma once' nella parte superiore di ciascuna intestazione. –

risposta

0

A meno che non si stia progettando di replicare la libreria Boost, questo sembra un modo folle per codificare un sistema di unità. L'hackery dei modelli è raramente l'opzione migliore.

Invece, usa una classe! Codice non reale di seguito:

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

E così via per implementare la conversione di nuovo a qualsiasi unità che si desidera. Fondamentalmente scegli una unità base in cui tutto è archiviato e convertito in e da quello. Se stai facendo SI, forse grammi, metri, secondi, Kelvin, ecc.

+0

Questo non è Boost.Un modo, quindi non risponde alla domanda. – Ruslan