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
Template
Template <> Class Valuetraits Template <> Class Valuetraits Template template 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 Private: valueType m_amount; unit_base #define QUANTITY Quantity Template #ENDIF / * _QUANTINTITY_H_ * / Weight: #ifndef _weight_h_ # define _Weight_H_ #include "../quantity.h" Class weightvalidator {}; typef Quantity / * Template 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 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;}