2011-10-06 50 views
3

我需要代表Volts,Ampers和Watts及它們之間的關係(例如W = V * I)。C++:是否有一種較爲冗長的方式來表示自定義數字類型?

這就是我隨之而來的,但它看起來非常冗長。有關如何使它更簡潔的想法?

#include <stdio.h> 
#include <iostream> 


template<class T>  
class double_val { 
public: 
    explicit double_val(double val):_val(val) { }; 
    double_val(const T& other) { 
     _val = other._val; 
    } 
    T& operator=(const T &other) { 
     _val = other._val; 
     return *this; 
    } 
    T operator+ (const T& other) const { 
     return T(this->_val + other._val); 
    } 
    T operator+ (double val) const { 
     return T(this->_val + val); 
    } 
    T operator- (const T& other) const { 
     return T(this->_val - other._val); 
    } 
    T operator- (double val) const { 
     return T(this->_val - val); 
    } 
    T operator* (const T& other) const { 
     return T(this->_val * other._val); 
    } 
    T operator* (double val) const { 
     return T(this->_val * val); 
    } 
    T operator/ (const T& other) const { 
     return T(this->_val/other._val); 
    } 
    T operator/ (double val) const { 
     return T(this->_val/val); 
    } 
    bool operator== (const T& other) const{ 
     return this->_val == other._val; 
    } 
    bool operator!= (const T& other) const{ 
     return this->_val != other._val; 
    } 
    bool operator > (const T& other) const{ 
     return this->_val > other._val; 
    } 
    bool operator >= (const T& other) const{ 
     return this->_val >= other._val; 
    } 
    bool operator < (const T& other) const{ 
     return this->_val < other._val; 
    } 
    bool operator <= (const T& other) const{ 
     return this->_val <= other._val; 
    } 
    void val(double val){ 
     _val = val; 
    } 
    double val() const { 
     return _val ; 
    } 
    virtual const char* name() const = 0; 

private: 
    double _val; 
}; 
template<class T> 
std::ostream& operator<<(std::ostream &os, const double_val<T> &t) { 
    return os << t.val() << " " << t.name(); 
} 


class Amper:public double_val<Amper> { 
public: 
    Amper(double val):double_val<Amper>(val) {} 
    const char* name() const { 
     return "Amper"; 
    } 
}; 

class Volt:public double_val<Volt> { 
public: 
    Volt(double val):double_val<Volt>(val) {} 
    const char* name() const { 
     return "Volt"; 
    } 
}; 

class Watt:public double_val<Watt> { 
public: 
    Watt(double val):double_val<Watt>(val) {} 
    const char* name() const { 
     return "Watt"; 
    } 
}; 

// Watt = I * V 
Watt operator* (const Volt &v, const Amper& a) { 
    return Watt(a.val() * v.val()); 
} 
Watt operator* (const Amper &a, const Volt& v) { 
    return Watt(a.val() * v.val()); 
} 

// Volts = Watts/Ampers 
Volt operator/(const Watt &w, const Amper& a) { 
    return Volt(w.val()/a.val()); 
} 

// Ampers = Watts/Volts 
Amper operator/(const Watt &w, const Volt& v) { 
    return Amper(w.val()/v.val()); 
} 



int main(int argc, char **argv) { 
    using namespace std; 
    Watt w = Volt(66) * Amper(7); 
    Amper a = w/(Volt(646) * Volt(444)); 

    cout << a << endl; 

    return 0; 
} 

(注:我intentionaly省略運營商雙(),因爲我想避免像伏禁止的OPS(4)+瓦特(6))

+2

查看此Boost庫:http://www.boost.org/doc/libs/1_47_0/doc/html/boost_units.html - 它可以滿足您的需求:單位轉換,維數分析等。 – Archie

+0

有你看了Boost.Units?看起來非常適合你的任務。 – pmr

回答

10

確實是有一個更簡潔庫的形式方式,Boost.Units它將SI單元定義爲類型安全類模板實例。

特別是,它定義了單位volt(s)ampere(s)watt(s)

+1

像往常一樣在C++中,所有方法導致BOOST :) – GabiMe

2

如果客戶端代碼合作,您可以使用std::rel_ops刪除邏輯操作。 rel_ops根據您的==和<運算符定義了一堆邏輯運算符。

但是這是有問題的 - 它強制客戶端使用rel_ops,並且rel_ops突然讓任何帶有==和<運算符的類與所有其他運算符進行比較。這可能不是你想要的。

IMO更好的選擇是使用boost operators庫,這對於數值類型來說似乎很理想,因爲它提供了數字類型所需的所有各種運算符。您只需定義幾個基本操作符,然後根據您的規範填寫其餘部分。要從提升文檔的例子偷

template <class T> 
class point // note: private inheritance is OK here! 
    : boost::addable< point<T>   // point + point 
    , boost::subtractable< point<T>  // point - point 
    , boost::dividable2< point<T>, T // point/T 
    , boost::multipliable2< point<T>, T // point * T, T * point 
     > > > > 
{ 
public: 
    point(T, T); 
    T x() const; 
    T y() const; 

    point operator+=(const point&); 
    // point operator+(point, const point&) automatically 
    // generated by addable. 

    point operator-=(const point&); 
    // point operator-(point, const point&) automatically 
    // generated by subtractable. 

    point operator*=(T); 
    // point operator*(point, const T&) and 
    // point operator*(const T&, point) auto-generated 
    // by multipliable. 

    point operator/=(T); 
    // point operator/(point, const T&) auto-generated 
    // by dividable. 
private: 
    T x_; 
    T y_; 
}; 
+0

好東西。謝謝 – GabiMe

3

Boost.Units是您需要一個很好的解決方案,因爲它提供電壓,電流,功率和適當的運營商的respresentation開箱。

Boost.Operators解決了不是SI單位的自定義數字類型的一般情況下的這個問題。

相關問題