2012-07-19 41 views
5

Tôi đang cố tạo đơn vị cho đồng hồ và ki lô mét. Tôi muốn sau đó tổng hợp và chuyển đổi chúng cho phù hợp. Tôi biết rằng thư viện boost :: units đã có hệ thống SI, nhưng tôi muốn tạo tất cả từ đầu, bởi vì sau đó tôi cần tạo các hệ thống của riêng mình cho các dự án của mình (vì vậy tôi đang làm điều này để tìm hiểu). Mục đích của tôi là để tuyên bố một "Chiều dài" biến mà có thể thay đổi đơn vị sử dụng: ví dụ tôi muốn viếtTạo chuyển đổi do người dùng xác định

Length xLength1 = 5350 * Meters + 2 Kilometers; 

Đối với mục đích này, tôi đã tạo length.h tập tin, bao gồm định nghĩa về mét và km, và cuối cùng tôi tuyên bố việc chuyển đổi giữa hai đơn vị sau đây:

#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 

Sau đó, tôi tạo ra các tập tin units.h trong đó tôi xác định hệ thống đơn vị của riêng tôi

#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 

Ít nhất, tôi sử dụng tiêu đề này trong chức năng chính của tôi

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

dự án này biên dịch, nhưng Nó không làm những gì tôi muốn. Khi tôi in biến xLength2, tôi nhận được 1500 m thay vì 1500 km hoặc 1500000 m. Tổng số cũng sai, bởi vì tôi vâng lời 1800 m. Nó giống như tôi xem xét km như mét và chuyển đổi không hoạt động.

Tôi đang làm gì sai?

+0

Bạn xác định 'Kilometer' giống với' Mét'. Tôi không nhớ lại cách nào là cách ưa thích để xác định 'Kilometer' (có lẽ có một macro khác), nhưng bạn có thể thử một cái gì đó như' const Length Kilometer = 1000 * Meters; '(xáo trộn thứ tự các định nghĩa). –

+1

Nhưng trong trường hợp này tôi không thể viết và nhận giá trị tính bằng kilômét, nhưng chỉ tính bằng mét. Tôi muốn khả năng làm việc với cả hai đơn vị, và sử dụng cả hai giá trị khi cần thiết. – Jepessen

+0

Chỉ cần một người đứng đầu, nếu bạn đang sử dụng MSVC++ hoặc gcc, bạn có thể thay thế '#IFDEF LENGTH_H_' etc guards bằng' #pragma once' ở đầu mỗi tiêu đề. –

Trả lời

0

Trừ khi bạn đang dự án là nhân rộng thư viện Boost, điều này có vẻ như một cách điên rồ để mã hóa một hệ thống đơn vị. Mẫu hackery hiếm khi là lựa chọn tốt nhất.

Thay vào đó, hãy sử dụng một lớp học! Không phải mã thực bên dưới:

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

Và cứ thế để thực hiện chuyển đổi về bất kỳ đơn vị nào bạn muốn. Về cơ bản, bạn chọn một đơn vị cơ sở mà mọi thứ được lưu trữ dưới dạng và chuyển đổi thành và từ đó. Nếu bạn đang thực hiện SI, có thể là gam, mét, giây, kelvin, v.v.

+0

Đây không phải là Boost.Units cách, do đó không trả lời câu hỏi. – Ruslan

Các vấn đề liên quan