Analytical mode - measured C ++ implementation - perfect version

zhaozj2021-02-11  181

The following is an improved version of http://www.9cbs.net/develop/Article/14/14487.SHTM, which was originally followed by a comment, but as a comment, a lot of text will be lost, Very strange. This article is the result of my discussion with Singleracer. Personally think that it is almost close to perfection, hoping to help everyone, you can add other unit systems and units.

Template class:

#ifndef _quantity_h_ # define _Quantity_H_

#ifdef _debug # Define assert_same_type (t1, t2) DO {T1 V = T2 (); v;} while (false) # Else # define assert_same_type (t1, t2) #ENDIF

#include "singleton.h"

Template struct unittraits {typedef unittype :: validator validator;

Template class valuetraits {public: static bool equal (const valuetepe & l, const valuetepe & r) {return (l == r);

Template <> Class Valuetraits {public: static Bool Equal (const Double & l, const Double & r) {static double precision = 0.000000001; Return (L - R

Template <> Class Valuetraits {public: Static Bool Equal (Const Float & l, Const Float & R) {Static Float Precision = 0.000000001F; Return (L - R

Template > Class Quantity {public: typedef unitvalidator validator;

template Quantity (const ValueType & amount, const UnitType &): m_amount (amount), m_unit (Singleton > :: Instance ()) {ASSERT_SAME_TYPE (UnitTraits :: Validator, Validator);} ~ quantity () {} quantity (all): m_amount (other.m_amount), m_unit (other.m_unit) {} Quantity & Operator = (const QUANTITY & RHS) {IF (& rhs! = This ) {m_amount = rhs.m_amount; m_unit = rhs.m_unit;} return * this;} template void convert (const UnitType &) {ASSERT_SAME_TYPE (UnitTraits :: Validator, Validator); unit_base * unit = Singleton > :: Instance (); if (unit = m_unit!) {m_amount = m_unit-> to_standard (m_amount); m_unit = unit; m_amount = m_unit-> from_standard (m_amount); }} Quantity & Operator = (const QUANTITY & RHS) {m_amount = Unitize (RHS); return * this;} quantity & operator - = (const QUANTITY & RHS) {m_amount - = unitize (rhs); return * this; } BOOL Operator == (const QUANTITY & RHS) {RETURN _TRAITS :: Equal (m_amount, unitize (rhs));} Bool Operator> (const QUANTITY & RHS) {RETURN M_AMOUNT> Unitize (rhs);} Bool Operator> = (const QUANTITY & RHS) {RETURN (M_AMOUNT> Unitize (RHS)? True: (M_Amount, Unitize (RHS)))))))))))))))))))))))));} Bool Operator <(const QUANTITY & RHS) {RETURN M_AMOUNT

Private: // Does not need to conversion for the same operation, there is no loss of failure VALUETYPE UNITIZE (Const Quantity & RHS) {if (m_unit == rhs.m_unit) Return RHS.M_AMOUNT; Else Return M_Unit-> from_Standard rhs.m_unit-> to_standard (rhs.m_amount));} private: template class unit_base {public: virtual ValueType to_standard (const ValueType & val) const = 0; virtual ValueType from_standard (const ValueType & val) const = 0;}; // the design unit_wrap singleton, this simply comparing unit is the same as a simple pointer comparison template class unit_wrap: public unit_base {protected: unit_wrap () {} ~ unit_wrap () {} public: virtual ValueType to_standard (const ValueType & val) const {return UnitType :: to_standard (val);} virtual ValueType from_standard (const ValueType & val) const {return UnitType :: from_standard (val);}};

Private: valueType m_amount; unit_base * m_unit;

#define QUANTITY Quantity template QUANTITY inline _cdecl operator (const QUANTITY & a, const QUANTITY & b) {return (QUANTITY (a) = b);}

Template Quantity Inline_CDecl Operator- (Const Quantity & A (CONST QUANTITY & B) {Return (Quantity (a) - = b);}

#ENDIF / * _QUANTINTITY_H_ * /

Weight: #ifndef _weight_h_ # define _Weight_H_

#include "../quantity.h"

Class weightvalidator {}; typef Quantity Weight;

/ * Template Weight inline _cdecl operator * (const ValueType & value, const UnitType & unit) {return Weight (value, unit);} * / class Kilogram {public: typedef WeightValidator Validator; static double to_standard (double VAL) {Return Val;} static double from_standard (double val) {returnign;}};

Class gramme {public: typedef weightvalidator value; static double to_standard (double val) {returnaval / 1000.0;} static double from_standard (double val) {return val * 1000.0;}};

Kilogram _kg; gramme _g;

#ENDIF / * _WEIGHT_H_ * /

Length: #ifndef _length_h_ # define _length_h_

#include "../quantity.h"

Class LengthValidator {}; type, lengthvalidator> length;

/ * Template length inline _cdecl operator * (Const UnitType & Value, Const UnitType & Unit) {Return Length (Value, Unit);} * /

Class meter {public: typedef lengthValidator Validator; static double to_standard (double val) {retur;} static double from_standard (double val) {retur;}};

Class kilometer {public: typef length to_standard (double val) {return val * 1000.0;} static double from_standard (double val) {returnaval / 1000.0;}};

Meter_m; kilometer _km;

#ENDIF / * _LENGTH_H_ * /

Test code: // Quantity.cpp: Defines the entry point for the console application.///

#include "stdafx.h" #include "weight.h" #include "length.h"

Void testWeight () {Weight W1 (1.0, _kg); // Constructor Weight W2 (1.0, _g); // Constructor

Weight w3 = w1; // copy constructor w3 = W2; // assignment operation

Weight W4 (1.0, _kg); W4 = W1; // The same unit adds W4 = W2; // Different units plus Weight W5 = W1T W1T W1T W1T W5 = W1T W1T W1T W5 = W1T W5 = W1T W1T W1T W5 = W5 = W5 = W5 = W5 = W5 = W5 = W4 W2; / / Different units add

Weight W6 (2.0, _kg); w6 - = w1; // The same unit is subtracted W6 - = W2; // Different units minus Weight W7 = W5 - W1; // The same unit reduction W7 = W5 - W2; / / Different units subtract // Compare Weight A (1.0, _kg); Weight B (2.0, _kg); Weight C (2000.0, _G); Weight D (3000.0, _G); BOOL F = (a

// Unit Convert Weight W10 (1.0, _kg); w10.convert (_G); w10.convert (_KG);

Void TestLength () {Length L1 (1.0, _km); // Constructor Length L2 (1.0, _M); // Constructor

Length L3 = L1; // Copy Construction Function L3 = L2; // Assignment

Length L4 (1.0, _km); L4 = L1; // The same unit adds L4 = L2; // Different units plug in Length L5 = L4 L1; // The same unit plus L5 = L4 L2; / / Different units add

Length L6 (2.0, _km); L6 - = L1; // The same unit is subtracted L6 - = L2; // Different units minus LENGTH L7 = L5 - L1; // The same unit decreases L7 = L5 - L2; / / Different units

/ / Compare Length A (1.0, _km); Length B (2.0, _M); Length D (3000.0, _M); BOOL F = (a

/ / Unit Convert Length L10 (1.0, _km); l10.convert (_m); l10.convert (_KM);

Void TesterRROR () {# if (0) Weight W1; // No default constructor Length L1; // No default constructor # endif # if (0) Weight W2 (1.0, _km); // Error unit Length L2 (1.0, _g); // Error unit # endif # if (0) Weight W3 (1.0, _KG); Length L3 (1.0, _m); w3.convert (_KM); // Error unit L3. Convert (_G); // Error # endif # if (0) Weight W4 (1.0, _kg); Length L4 (1.0, _m); W4 = L4; // Error type W4 - = L4; // Error type # ENDIF # if (0) Weight W5 (1.0, _kg); Length L5 (1.0, _m); BOOL F = (W5 == L5); f = (W5> L5); f = (W5

INT Main (int Argc, char * argv []) {testweight (); testlength (); testerror (); return 0;}

转载请注明原文地址:https://www.9cbs.com/read-5858.html

New Post(0)