Verwalten von Umrechnungen mit einer Klasse (C++)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Umrechnen von Maßeinheiten (C++)

Es ist stets möglich, Umrechnungsfunktionen zur Registrierung von Maßeinheiten zu verwenden. Dieses Vorgehen kann jedoch in manchen Fällen die Definition sehr vieler Funktionen erfordern, die im Grunde dasselbe ausführen.

Statt einer Gruppe von Umrechnungsfunktionen, die sich nur in dem Wert eines Parameters oder einer Variable unterscheiden, können Sie eine Klasse definieren, die diese Art von Umrechnungen handhabt. Beispielsweise werden seit der Einführung des Euro Standardformeln zur Umrechnung der verschiedenen europäischen Währungen eingesetzt. Obwohl die Umrechnungsfaktoren konstant bleiben (im Gegensatz zum Faktor für die Umrechnung von US-Dollar in Euro), ist es aus zweierlei Gründen nicht möglich, zur Umrechnung europäischer Währungen einfache Umrechnungsfaktoren zu verwenden:

  • Die Umrechnungsbeträge müssen auf eine währungsspezifische Anzahl von Stellen gerundet werden.
  • Der Umrechnungsfaktor, der für die Funktion Convert definiert werden muss, ist invers zu dem Faktor, der in den Euro-Umrechnungskonventionen festgelegt ist.

Diese Schwierigkeiten lassen sich mit folgenden Umrechnungsfunktionen beheben:

double __fastcall FromEuro(const double AValue, const double Factor,
     TRoundToRange FRound) {
     return(RoundTo(AValue * Factor, FRound));
 }
 
 double __fastcall ToEuro(const double AValue, const double Factor) {
     return (AValue / Factor);
 }

Problematisch ist hier, dass diese Umrechnungsfunktion zusätzliche Parameter erfordert, sodass Sie nicht für jede europäische Währung dieselbe Funktion registrieren können. Damit Sie nicht für jede europäische Währung zwei Funktionen dieser Art erstellen müssen, definieren Sie diese beiden Funktionen als Member einer Klasse.

Definieren der Umrechnungsklasse

Die Klasse muss von TConvTypeFactor abgeleitet werden. Die Klasse TConvTypeFactor definiert die beiden Methoden ToCommon und FromCommon, die Umrechnungen in die bzw. aus der Grundeinheit einer Umrechnungsfamilie durchführen (hier in und aus Euro). Wie die Funktionen, die beim Registrieren einer Maßeinheit verwendet werden, verarbeiten diese Methoden keine zusätzlichen Parameter. Sie müssen daher die Anzahl der zu rundenden Stellen und den Umrechnungsfaktor als private-Member der Umrechnungsklasse definieren. Dies wird im Beispiel "EuroConv" im Verzeichnis "demos\ConvertIt" (siehe euroconv.pas) gezeigt:

class PASCALIMPLEMENTATION TConvTypeEuroFactor
 		: public Convutils::TConvTypeFactor {
 private:
 	TRoundToRange FRound;
 
 public:
 	__fastcall TConvTypeEuroFactor(const TConvFamily AConvFamily,
 			const AnsiString ADescription, const double AFactor,
 			const TRoundToRange ARound);
 	TConvTypeFactor(AConvFamily, ADescription, AFactor);
 	virtual double ToCommon(const double AValue);
 	virtual double FromCommon(const double AValue);
 }

Der Konstruktor weist diesen private-Membern Werte zu:

__fastcall TConvTypeEuroFactor::TConvTypeEuroFactor
     (const TConvFamily AConvFamily, const AnsiString ADescription,
     const double AFactor, const TRoundToRange ARound)
     : TConvTypeFactor(AConvFamily, ADescription, AFactor); {
     FRound = ARound;
 }

Die beiden Umrechnungsfunktionen verwenden einfach diese private-Member:

virtual double TConvTypeEuroFactor::ToCommon(const double AValue) {
     return (RoundTo(AValue * Factor, FRound));
 }
 
 virtual double TConvTypeEuroFactor::ToCommon(const double AValue) {
     return (AValue / Factor);
 }

Deklarieren von Variablen

Nachdem die Umrechnungsklasse deklariert wurde, deklarieren Sie wie bei jeder anderen Umrechnungsfamilie zunächst die Bezeichner:

TConvFamily cbEuro;
 TConvType euEUR; // EU euro
 TConvType euBEF; // Belgian francs
 TConvType euDEM; // German marks
 TConvType euGRD; // Greek drachmas
 TConvType euESP; // Spanish pesetas
 TConvType euFFR; // French francs
 TConvType euIEP; // Irish pounds
 TConvType euITL; // Italian lire
 TConvType euLUF; // Luxembourg francs
 TConvType euNLG; // Dutch guilders
 TConvType euATS; // Austrian schillings
 TConvType euPTE; // Protuguese escudos
 TConvType euFIM; // Finnish marks

Registrieren der Umrechnungsfamilie und die anderen Units

Jetzt können Sie die Umrechnungsfamilie sowie die europäischen Währungen unter Verwendung der neuen Umrechnungsklasse registrieren. Sie registrieren diese Umrechnungsfamilie auf dieselbe Weise wie die anderen Umrechnungsfamilien:

cbEuro = RegisterConversionFamily("European currency");

Zur Registrierung der einzelnen Umrechnungstypen erstellen Sie jeweils eine Instanz der Umrechnungsklasse, die den Umrechnungsfaktor und die Zahl der zu rundenden Stellen für die betreffende Währung repräsentiert, und rufen die Methode RegisterConversionType auf.

TConvTypeInfo *pInfo = new TConvTypeEuroFactor(cbEuro, " EUEuro ", 1.0, -2);
 if (!RegisterConversionType(pInfo, euEUR))
 	delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " BelgianFrancs ", 40.3399, 0);
 if (!RegisterConversionType(pInfo, euBEF))
 	delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " GermanMarks ", 1.95583, -2);
 if (!RegisterConversionType(pInfo, euDEM))
 	delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " GreekDrachmas ", 340.75, 0);
 if (!RegisterConversionType(pInfo, euGRD) delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " SpanishPesetas ", 166.386, 0);
 if (!RegisterConversionType(pInfo, euESP) delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " FrenchFrancs ", 6.55957, -2);
 if (!RegisterConversionType(pInfo, euFFR) delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " IrishPounds ", 0.787564, -2);
 if (!RegisterConversionType(pInfo, euIEP) delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " ItalianLire ", 1936.27, 0);
 if (!RegisterConversionType(pInfo, euITL) delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " LuxembourgFrancs ", 40.3399, -2);
 if (!RegisterConversionType(pInfo, euLUF) delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " DutchGuilders ", 2.20371, -2);
 if (!RegisterConversionType(pInfo, euNLG) delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " AutstrianSchillings ", 13.7603, -2);
 if (!RegisterConversionType(pInfo, euATS) delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " PortugueseEscudos ", 200.482, -2);
 if (!RegisterConversionType(pInfo, euPTE) delete pInfo;
 pInfo = new TConvTypeEuroFactor(cbEuro, " FinnishMarks ", 5.94573, 0);
 if (!RegisterConversionType(pInfo, euFIM) delete pInfo;

Verwenden der neuen Maßeinheiten

Die registrierten Maßeinheiten stehen nun Anwendungen für Umrechnungen zur Verfügung. Die globale Funktion Convert kann Beträge in alle europäischen Währungen, die in der neuen Familie cbEuro registriert sind, umrechnen. Mit dem folgenden Aufruf werden z.B. Italienische Lire in Deutsche Mark umgerechnet:

Edit2->Text = FloatToStr(Convert(StrToFloat(Edit1->Text), euITL, euDEM));

Siehe auch