Hallo Martin,
Würde ich nicht machen. Das scheint so bequem, hat aber Haare
auf den Zähnen:
irgendwann willst Du so ein Ding, als Template-Typ, in einen
Container stecken, und der Compiler kriegt dann die Krise,
weil er nicht weiss, ob das ein „classTyp“ oder ein
„stringvar“ sein soll („zweifelhaft“). Mit meiner Empfehlung
nicht.
Ich hätte betonen sollen, daß man das vorsichtig verwenden soll. Ich denke, bei der Bruch-Klass ist das in Ordnung.
sin(Bruch(2,3));
Gut, das geht so. Ich kann das selbe aber auch mit einer
ordinären getAny() machen, fast um das selbe Geld:
sin( (Bruch(2,3)).getAny() );
Dafür habe ich doch keine Objektorientierung. Ich will mich gerade nicht darum kümmern, ob ich direkt ein double übergebe oder einen Bruch.
und so aufrufen. Vorsicht ist bei der Typumwandlung:
Bruch(1, 2) + 2 --> Typ Bruch, da ‚2‘ automatisch in
‚Bruch‘ umgewandelt wird (Konstruktor ‚Bruch(int)‘)
Bruch(1, 2) + 2.0 --> Typ double, da ‚Bruch‘
automatisch in ‚double‘ umgewandelt wird.
Na, die zweite Zeile wäre OK, aber: die „2“ wird in „Bruch“
umgewandelt? Deinen Optimismus in Ehren, aber warum sollte ein
Compiler soetwas machen? Hat die „2“ jetzt einen
operator
Bruch() {}
?
Oder habe ich Dich da missverstanden?
Nein, Bruch hat einen impliziten Konstruktor: Bruch(int i), der reicht aus:
dknof@sybille:t$ cat Bruch.cpp
#include
class Bruch {
public:
Bruch(int const i) :
z(i), n(1) { }
Bruch(int const z, int const n) :
z(z), n(n) { }
/\*
operator double()
{ return (static\_cast(this-\>z) / this-\>n); }
\*/
int z, n;
};
Bruch operator+(Bruch const& b1, Bruch const& b2)
{ return Bruch(b1.z \* b2.n + b1.n \* b2.z, b1.n \* b2.n); }
std::ostream& operator
Probleme gibt es, wenn ich auch den operator double dazuschalte, da dann der Compiler nicht zwischen operator+(double, int) und operator+(Bruch, Bruch) entscheiden kann. Ist hingegen der Konstruktor 'Bruch(int)' explizit: 'explicit Bruch(int)', dann wird der double-Konverter genommen, da ich die int-\>Bruch-Konvertierung explizit angeben muß:
dknof@sybille:t$ diff Bruch.cpp Bruch2.cpp; g++ -Wall Bruch2.cpp && ./a.out
5c5
explicit Bruch(int const i) :
9d8
std::cout (c) + b
Praktisch habe ich für meine Bruch-Klasse mit die Kombinationen Bruch und int (bei den einzelnen Operatoren) separat definiert und die double-Typkonvertierung verwendet.
Gruß
Diether