Vererbung und Operatorüberladung
-
Moin zusammen,
Ich wollte fragen, ob mir jemand bei dieser Aufgabe behilflich sein kann.
Ich soll zwei Klassen erstellen.
In der ersten Klasse wird ein Vektor erstellt im Konstruktor, danach noch zwei Operatorüberladungen.
Die erste soll zwei Vektoren addieren und die zweite den Ausgabe Operator überladen um die addierten Vektoren auszugeben.
Soweit so gut.
Mein Problem ist jetzt, dass ich in der zweiten Klassen die von der ersten vererbt ist eine Methode erstellen soll, die prüft ob die beiden Vektoren orthogonal zu einander liegen.
Heißt ich muss prüfen ob das Skalarprodukt "0" ergibt.Ich bekomme das mit dem Skalarprodukt in der vererbten Klasse aber einfach nicht hin..
So weit bin ich schon mal.
Fehlt nur noch die Methode mit dem Skalarprodukt.Vielen Dank schon mal
#include <iostream> using namespace std; class Vec2D { public: double x,y; //Konstruktor Vec2D(double a, double b) : x(a), y(b){} //Operator überladung "+" Vec2D operator+ (Vec2D p) { return Vec2D(x + p.x, y + p.y); } //Operator Überladung "<<" friend ostream& operator<<(ostream& os, const Vec2D& output){ os << "<" <<output.x << "," << output.y << ">" <<endl; return os; } }; class Vec2Dext : public Vec2D{ public: //Konstruktor Vec2Dext(double a, double b) : Vec2D(a,b){ x = a; y = b; } }; int main() { Vec2Dext Vek1(2,5); Vec2Dext Vek2(3,5); Vec2D Ergebnis = Vek1 + Vek2; cout<<Ergebnis; return 0; }
-
@Pneox sagte in Vererbung und Operatorüberladung:
//Konstruktor Vec2Dext(double a, double b) : Vec2D(a,b){ x = a; y = b; }
Die Zuweisungen im Body dieses Konstruktors sind überflüssig.
x
undy
werden schon durch den Basisklassenkonstruktor initialisiert, den Du ja aufrufst.@Pneox sagte in Vererbung und Operatorüberladung:
Mein Problem ist jetzt, dass ich in der zweiten Klassen die von der ersten vererbt ist eine Methode erstellen soll, die prüft ob die beiden Vektoren orthogonal zu einander liegen.
Heißt ich muss prüfen ob das Skalarprodukt "0" ergibt.Ich bekomme das mit dem Skalarprodukt in der vererbten Klasse aber einfach nicht hin..
Was hast Du versucht? Woran scheiterts?
return (x * other.x + y * other.y) == 0;
// edit: Oh,double
s. Dann lieber prüfen ob das Ergebnis klein genug ist.
?
-
bool skalar(Vec2Dext V1, Vec2Dext V2) { if(((x * V1.x) + (y * V2.y)) == 0){ return true; } return false; }
Hab es so probiert, geht aber auch nicht..
-
-
@Pneox sagte in Vererbung und Operatorüberladung:
bool skalar(Vec2Dext V1, Vec2Dext V2) { if(((x * V1.x) + (y * V2.y)) == 0){ return true; } return false; }
Hab es so probiert, geht aber auch nicht..
Das geht doch so noch nicht mal durch den Compiler. Wo kommen denn
x
undy
her?
-
#include <iostream> using namespace std; class Vec2D { public: double x,y; //Konstruktor Vec2D(double a, double b) : x(a), y(b){} //Operator überladung "+" Vec2D operator+ (Vec2D p) { return Vec2D(x + p.x, y + p.y); } //Operator Überladung "<<" friend ostream& operator<<(ostream& os, const Vec2D& output){ os << "<" <<output.x << "," << output.y << ">" <<endl; return os; } Vec2D operator* (Vec2D p) { return Vec2D(x * p.x, y * p.y); } }; class Vec2Dext : public Vec2D{ public: //Konstruktor Vec2Dext(double a, double b) : Vec2D(a,b){} bool skalar(Vec2Dext V1, Vec2Dext V2) { if(((x * V1.x) + (y * V2.y)) == 0){ return true; } return false; } }; int main() { Vec2Dext Vek1(2,-2); Vec2Dext Vek2(3,3); Vec2D ErgebnisAdd = Vek1 + Vek2; cout<<ErgebnisAdd; Vec2D ErgebnisMulti = Vek1 * Vek2; cout<<ErgebnisMulti; if (Vek1.skalar(Vek1, Vek2)){ cout<<"JA"; } else{ cout<<"Nein"; } return 0; }
So hier nochmal alles bis zum jetzigen Zeitpunkt.
Bei den Vektoren kommt "NEIN" raus, obwohl das Skalarprodukt hier gleich "0" ist.
Vielleicht ist es auch eine Kleinigkeit die ich übersehe.
-
Wie wäre es, wenn Du
skalar() const
zu einem Member vonVec2Dext
machst und nur einenVec2
(als konstante Referenz) als Parameter nimmst? Dann würde die Verwendung vonx
undy
passen.@Pneox sagte in Vererbung und Operatorüberladung:
if(((x * V1.x) + (y * V2.y)) == 0){
Kann nicht passen, weil jetzt sind schon 3 Vektoren im Spiel: Der, für den
skalar()
aufgerufen wird (x
undy
),V1
(V1.x
undV1.y
) undV2
(V2.x
undV2.y
).@Swordfish sagte in Vererbung und Operatorüberladung:
return (x * other.x + y * other.y) == 0;
// edit: Oh, doubles. Dann lieber prüfen ob das Ergebnis klein genug ist.Bei deinen im Beispiel gewählten "schönen" Zahlen mag ein direkter Vergleich mit
0
noch gutgehen, aber in der Regel muss man beachten, daß Fließkommazahlen nicht beliebig genau sind und es zu Abweichungen im Ergebnis kommen kann. Deshalb kann es schon mal vorkommen, daß etwas, das im Dezimalsystem mit beliebiger Genauigkeit genau0
ist, mitfloat
s oderdouble
s nicht genau0
ist sondern eine sehr kleine Zahl <>0
.
-
#include <iostream> using namespace std; class Vec2D { public: double x,y; //Konstruktor Vec2D(double a, double b) : x(a), y(b){} //Operator überladung "+" Vec2D operator+ (Vec2D p) { return Vec2D(x + p.x, y + p.y); } //Operator Überladung "<<" friend ostream& operator<<(ostream& os, const Vec2D& output){ os << "<" <<output.x << "," << output.y << ">" <<endl; return os; } Vec2D operator* (Vec2D p) { return Vec2D(x * p.x, y * p.y); } }; class Vec2Dext : public Vec2D{ public: //Konstruktor Vec2Dext(double a, double b) : Vec2D(a,b){} bool skalar(Vec2Dext V2) { int u; u =((x * V2.x) + (y * V2.y)); if ( u == 0 ){ return true; } return false; } }; int main() { Vec2Dext Vek1(3.8,-3.8); Vec2Dext Vek2(6.7,6.7); Vec2D ErgebnisAdd = Vek1 + Vek2; cout<<ErgebnisAdd; Vec2D ErgebnisMulti = Vek1 * Vek2; cout<<ErgebnisMulti; if (Vek1.skalar(Vek2)){ cout<<"JA"; } else{ cout<<"Nein"; } return 0; }
So jetzt funktioniert es!
Dankeschön an alle
-
#include <limits> #include <cmath> // ... bool Vec2Dext::skalar(Vec2Dext const &V2) const { return std::fabs(x * V2.x + y * V2.y) < std::numeric_limits<double>::epsilon(); // *) }
* ) Ja, nicht optimal, aber schonmal besser als
== 0
.
-
Sauber! Und jetzt machen wir das noch schön
- da du
Vec2D
als Basisklasse fürVec2Dext
benutzt solltest du einen virtuellen Destruktor fürVec2D
bereitstellen - Parameter, auf die nur lesend zugegriffen werden, sollten als const reference übergeben werden
- Funktionen, deren Ergebnisse nicht von Membern einer Klasse abhängen, sollten als freie Funktionen implementiert werden. Es gibt keinen Grund, warum
skalar
in seiner jetzigen Form als Member implementiert wird.
- da du
-
@DocShoe sagte in Vererbung und Operatorüberladung:
Es gibt keinen Grund, warum skalar in seiner jetzigen Form als Member implementiert wird.
Naja, schon:
@Pneox sagte in Vererbung und Operatorüberladung:
Mein Problem ist jetzt, dass ich in der zweiten Klassen die von der ersten vererbt ist eine Methode erstellen soll, die prüft ob die beiden Vektoren orthogonal zu einander liegen.
-
Es gibt keinen Grund, warum
skalar
in seiner jetzigen Form 2 Parameter erwartet. Die beiden Vektoren sind das Objekt selbst, auf demskalar
aufgerufen wird, und der zweite wird als einziger Parameter übergeben. Aber das hat swordfish ja schon gezeigt.Besser?
-
@DocShoe yay
-
@DocShoe sagte in Vererbung und Operatorüberladung:
Sauber! Und jetzt machen wir das noch schön
- da du
Vec2D
als Basisklasse fürVec2Dext
benutzt solltest du einen virtuellen Destruktor fürVec2D
bereitstellen
Ich bin mir etwas unschlüssig, ob man nicht lieber erwähnen sollte, dass Polymorphie ein C++ ein optionales Feature ist und man einen virtuellen Destruktor nur dann benötigt, wenn es auch nutzt. Wahrscheinlich fahren Anfänger aber besser, wenn sie Vererbung erstmal nur mit polymorphen Klassen machen, das könnte helfen Überraschungen zu vermeiden.
Mit dem virtuellen Destruktor macht man jedenfalls erstmal nichts falsch - man sollte ihn nur dann weglassen, wenn man weiss, warum man es tut
- da du