ERLEDIGT
JA
JA
ANTWORTEN
15
15
ZUGRIFFE
531
531
EMPFEHLEN
-
Hallo zusammen,
im Rahmen eines Praktikums soll ich eine eigene Klasse "Vektor" definieren, die ein paar Funktionen enthält. Die einfache Ausgabe von z.B. der X-Koordinate ist auch kein Problem, doch wenn ich jetzt eine Funktion schreiben will, die 2 Vektoren addiert oder subtrahiert, gerade ich ins Schwimmen....
Genauer gesagt brauche ich 2 Funktionen, die ein bisschen unterschiedlich arbeiten sollen:
Wie versteht ihr das mit der ersten Funktion? Irgendwohin muss ich das Ergebnis doch ausgeben? Soll ich einen der überlieferten Vektoren überschreiben und als Ergebnis "benutzen"?- Eine Funktion, um die Differenz zweier Vektoren zu bilden
- Eine statische Funktion, welche zwei Vektoren addieren kann und einen Zeiger auf den neuen Vektor zurückgibt
In meiner vektor.h hatte ich mir das so gedacht:
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#ifndef vektor_H #define vektor_H class vektor { public: //konstruktor/destruktor vektor(double x, double y, double z); ~vektor(); private: //member double x; double y; double z; public: void ausgabe(); double getX(); double getY(); double getZ(); void getLength(); void sub(vektor*, vektor*); static vektor* add(vektor*, vektor*); }; #endif
Vektor.cpp
Code cpp:1 2 3 4 5 6 7 8 9 10
void sub(vektor* vektor1, vektor* vektor2) { // Unklar? } vektor* add(vektor vektor1, vektor vektor2) { vektor* add = new vektor(vektor1->getX() + vektor2->getX(), vektor1->getY() + vektor2->getY(), vektor1->getZ() + vektor2->getZ()); return add; }
Meine main.cpp sieht so aus. Sie enthält noch keine Funktionsaufrufe zum Addieren/Subtrahieren.
Code cpp:1 2 3 4
vektor* vektor1 = new vektor(1,1,1); vektor1->ausgabe(); vektor* vektor2 = new vektor(1,2,3); vektor2->ausgabe();
Könnt ihr mir jetzt vielleicht helfen und mir sagen, wie ich das solide auf die Beine stellen kann? Ich habe schon einige Stunden damit verbracht, doch irgendwie gab es immer Probleme mit Zeigern auf die Klasse und so weiter. Könnt ihr mir eine solide Umsetzung beschreiben?
Vielen Dank im vorraus.
Eroli
-
10.06.10 14:35 #2
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Hi.Mit Differenz ist vermutlich der Abstand der Vektoren gemeint. Da mußt du ja nur einen Wert zurückgeben.
Was meinst du damit?
\edit: Aha. Wenn du an die Funktion ein Objekt als Parameter übergibst und keinen Zeiger, dann kannst du auch nicht wie auf einen Zeiger darauf zugreifen:
Code cpp:1 2 3 4 5
vektor* add(const vektor* vektor1, const vektor* vektor2) { vektor* add = new vektor(vektor1->getX() + vektor2->getX(), vektor1->getY() + vektor2->getY(), vektor1->getZ() + vektor2->getZ()); return add; }
Das sieht doch bereits relativ gut aus.
Wobei nur an der Aufgabenstellung etwas merkwürdig ist, dass du mit Zeigern arbeiten mußt und nicht Referenzen verwenden darfst... (vermutlich ist das zu Übungszwecken so an den Haaren herbeigezogen).
Gruß
PS: die Getter und die ausgabe(), getLength() und sub() Methode sollten const sein. Genauso sollten die Parameter an die sub() und add Methode als konstante Zeiger (oder eben Referenzen) übergeben werden.Geändert von deepthroat (10.06.10 um 14:45 Uhr)
If at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
10.06.10 14:39 #3
- Registriert seit
- Jun 2007
- Ort
- Passau (Niederbayern)
- Beiträge
- 1.394
Hallo,
den Abstand der 2 Punkte (Differenz?) bekommst du über folgende Formel:
Code :1
a = Wurzel((x2 - x1)² + (y2 - y1)²);
Was mich allerdings wundert, ist dass deine sub()-Methode nichts zurückgibt. Bist du dir sicher, dass dort ein void stehen muss? Ansonsten würde ich da ein float oder ein double machen, je nachdem was du brauchst.
Gruß
BKÜber eine gute Bewertung freut sich jeder ;)
Bitte erledigte Threads als "Erledigt" markieren.
"Though a program be but three lines long, someday it will have to be maintained.''
-- Geoffrey James, "The Tao of Programming"
-
Du meinst also mit Differenz ist die Distanz zwischen diesen beiden Vektoren gemeint?
Falls ja, dann könnte ich einen double oder float zurückgeben, das ist kein Problem. Die Formel ist mir auch bekannt. Ich dachte bislang immer, dass die den folgenden Vektor von mir wollen:
ergebnis_X = v1.x - v2.x;
ergebnis_Y = v1.y - v2.y;
ergebnis_Z = v1.z - v2.z;
Nur wie krieg ich das Zeigerproblem bei der Additionsfunktion gelöst?
-
10.06.10 15:00 #5
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
If at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Man, ich liebe dieses Forum. Ihr seid so verdammt schnell

Fangen wir erstmal langsam mit der sub-Funktion an:
Vektor.h
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#ifndef vektor_H #define vektor_H class vektor { public: //konstruktor/destruktor vektor(double x, double y, double z); ~vektor(); private: //member double x; double y; double z; public: const void ausgabe(); const double getX(); const double getY(); const double getZ(); const void getLength(); const double sub(const vektor*, const vektor*); static vektor* add(const vektor*, const vektor*); }; #endif
Die Sub-Methode
Code cpp:1 2 3 4 5 6
const double sub(const vektor* v1, const vektor* v2) { return sqrt((v2->getX()-v1->getX())*(v2->getX()-v1->getX()) + (v2->getY()-v1->getY())*(v2->getY()-v1->getY()) + (v2->getZ()-v1->getZ())*(v2->getZ()-v1->getZ())); }
Und die Fehler:
Derselbe Fehler kommt für jede Verwendung von get(X/Y/Z)().passing 'const vektor' as 'this' argument of 'const double vektor::getX()' discards qualifiers
Ich bin jetzt erstmal relativ ratlos...
EDIT: Gibt es eigentlich kein eleganteres ^2Geändert von Eroli (10.06.10 um 15:30 Uhr)
-
10.06.10 15:50 #7
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Du hast offenbar die Methoden nicht als const deklariert wie bereits gesagt (damit war nicht gemeint den Rückgabetyp der Methoden als konstant zu definieren, das macht bei integralen Typen keinen Sinn):
Schreib dir doch eine square() Funktion.Code cpp:1 2 3 4 5 6 7 8 9 10
class vektor { ... public: double getX() const; ... }; double vektor::getX() const { ... }
Und verwende für die Fehlermeldungen einfach [code]..[/code] Tags, Zitate machen sich nicht so gut beim Zitieren...
GrußIf at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Hallo deepthroat,
habe die Header-Datei nach deinem Muster abgeändert. Das führte dazu, dass ich in der cpp alle Methoden, bis auf die sub-Methode auch ändern musste und zwar in:
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13
[...] void vektor::getLength() const { std::cout << "Length: " << sqrt(x*x + y*y + z*z) << std::endl; } double sub(const vektor* v1, const vektor* v2) { return sqrt((v2->getX()-v1->getX())*(v2->getX()-v1->getX()) + (v2->getY()-v1->getY())*(v2->getY()-v1->getY()) + (v2->getZ()-v1->getZ())*(v2->getZ()-v1->getZ())); }
Wenn ich bei der sub-Funktion jedoch ein const dahinter schreiben will, kommt der Fehler:
Code :1
non-member function `double sub(const vektor*, const vektor*)' cannot have `const' method qualifier
Warum ist das so? Warum muss ich das bei manchen Funktionen machen und bei anderen wiederrum nicht?
EDIT: Und wie rufe ich die Funktion jetzt auf? Da sie nicht statisch ist, müsste es doch z.B. so gehen:
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13
int main(int argc, char *argv[]) { cout << "hallo" << endl; vektor* vektor1 = new vektor(1,1,1); vektor1->ausgabe(); vektor* vektor2 = new vektor(1,2,3); vektor2->ausgabe(); cout << "Abstand von Vektor1 zu Vektor2: " << vektor1->sub(vektor1, vektor2) << endl; system("PAUSE"); return EXIT_SUCCESS; }
Das sieht aber doof aus. Da könnte ich mir den ersten Parameter sparen, dann wäre es schon etwas schöner. Oder die Funktion statisch deklarieren (soll aber laut Aufgabenstellung nicht sein, glaube ich). Statisch müsste es so aussehen, oder?
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13
int main(int argc, char *argv[]) { cout << "hallo" << endl; vektor* vektor1 = new vektor(1,1,1); vektor1->ausgabe(); vektor* vektor2 = new vektor(1,2,3); vektor2->ausgabe(); cout << "Abstand von Vektor1 zu Vektor2: " << vektor::sub(vektor1, vektor2) << endl; system("PAUSE"); return EXIT_SUCCESS; }
Geändert von Eroli (10.06.10 um 16:04 Uhr)
-
10.06.10 16:17 #9
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Genau so hatte ich es ja auch vorgeschlagen. Aber warum gibt die Funktion getLength nichts zurück? Wieso wird da etwas ausgedruckt? Das ist merkwürdig.
Wie hast du sub denn nun definiert? Vorhin hattest du es noch als Methode.
Wenn du ein konstantes Objekt hast, dann darfst du nur konstante Methoden dieses Objekts aufrufen (deswegen der erste Fehler). Innerhalb dieser Methoden darfst du dann den Zustand des Objekts nicht ändern (du darfst die Attribute x, y, z nicht verändern).
Statische Methoden oder Top-Level Funktionen sind nicht mit einem Objekt verbunden, da macht das const Schlüsselwort einfach keinen Sinn.
Ja.
Ja.
Ich würde sub vermutlich einfach als Top-Level Funktion definieren.
GrußIf at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Oh, ich dachte zuerst die Aufgabenstellung fordert das so, aber da steht:Genau so hatte ich es ja auch vorgeschlagen. Aber warum gibt die Funktion getLength nichts zurück? Wieso wird da etwas ausgedruckt? Das ist merkwürdig.
"Eine Funktion, in der die Länge des Vektors berechnet und zurückgegeben wird."
Du hast also vermutlich recht. Ich ändere das.
Mittlerweile ist es eine Funktion, die eine Gleitkommazahl zurückgibt (Ausschnitt):Wie hast du sub denn nun definiert? Vorhin hattest du es noch als Methode.
Code cpp:1 2 3 4 5 6 7 8
public: void ausgabe() const; double getX() const; double getY() const; double getZ() const; double getLength() const; double sub(const vektor*, const vektor*) const; static vektor* add(const vektor*, const vektor*);
Und die Implementierung:
Code cpp:1 2 3 4 5 6 7 8 9 10 11
double vektor::getLength() const { return sqrt(x*x + y*y + z*z); } double [B]vektor::[/B]sub(const vektor* v1, const vektor* v2) const { return sqrt((v2->getX()-v1->getX())*(v2->getX()-v1->getX()) + (v2->getY()-v1->getY())*(v2->getY()-v1->getY()) + (v2->getZ()-v1->getZ())*(v2->getZ()-v1->getZ())); }
Ich hatte das vektor:: vergessen, daher kam der berichtete Fehler (s.o.). Jetzt funktioniert der Funktionsaufruf.
Habe die Funktion jetzt auch wieder als konstant deklariert.
Ok, dann können wir jetzt ja zum nächsten Thema kommen: Der Additions-Funktion:
Gefordert wird: Eine statische Funktion, welche zwei Vektoren addieren kann und einen Zeiger auf den neuen Vektor zurückgibt.
Header
Code cpp:1
static vektor* add(const vektor*, const vektor*);
Implementation
Code cpp:1 2 3 4 5 6 7
vektor* add(const vektor* v1, const vektor* v2) { vektor* v3 = new vektor(v1->getX()+v2->getX() , v1->getY()+v2->getY() , v1->getZ()+v2->getZ()); return v3; }
So kompiliert das Programm sogar fehlerfrei, allerdings kann ich die Funktion nicht aufrufen:
Main.cpp
Code cpp:1
vektor* v3 = vektor::add(vektor1, vektor2);
Fehler:
Code :1
[Linker Error] undefined reference to `vektor::add(vektor const*, vektor const*)'
Wo kommt dieser Fehler jetzt wieder her?
EDIT: Argh, derselbe Fehler. Ich habe schon wieder das vektor:: bei "vektor::add" in vektor.cpp vergessen.... Jetzt klappt alles.Geändert von Eroli (10.06.10 um 16:41 Uhr)
-
10.06.10 16:43 #11
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
If at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Der Übersichtlichkeit halber und für alle, die damit auch Probleme haben (eher unwahrscheinlich
) hier nochmal das komplette Programm.
vektor.h
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#ifndef vektor_H #define vektor_H class vektor { public: //konstruktor/destruktor vektor(double x, double y, double z); ~vektor(); private: //member double x; double y; double z; public: void ausgabe() const; double getX() const; double getY() const; double getZ() const; double getLength() const; double sub(const vektor*, const vektor*) const; static vektor* add(const vektor*, const vektor*); }; #endif
vektor.cpp
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#include "vektor.h" #include <cmath> #include <iostream> vektor::vektor(double inX, double inY, double inZ) : x(inX) , y(inY) , z(inZ) { } vektor::~vektor() { } void vektor::ausgabe() const { std::cout << "X: " << x << std::endl; std::cout << "Y: " << y << std::endl; std::cout << "Z: " << z << std::endl; } double vektor::getX() const { return x; //return the value of "x" } double vektor::getY() const { return y; //return the value of "y" } double vektor::getZ() const { return z; //return the value of "z" } double vektor::getLength() const { return sqrt(x*x + y*y + z*z); } double vektor::sub(const vektor* v1, const vektor* v2) const { return sqrt((v2->getX()-v1->getX())*(v2->getX()-v1->getX()) + (v2->getY()-v1->getY())*(v2->getY()-v1->getY()) + (v2->getZ()-v1->getZ())*(v2->getZ()-v1->getZ())); } vektor* vektor::add(const vektor* v1, const vektor* v2) { vektor* v3 = new vektor(v1->getX()+v2->getX() , v1->getY()+v2->getY() , v1->getZ()+v2->getZ()); return v3; }
main.cpp (Natürlich kann man die Programmausgaben schöner gestalten)
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include <cstdlib> #include <iostream> #include <cmath> #include "vektor.h" using namespace std; int main(int argc, char *argv[]) { cout << "hallo" << endl; vektor* vektor1 = new vektor(1,1,1); vektor1->ausgabe(); vektor* vektor2 = new vektor(1,2,3); vektor2->ausgabe(); cout << "Abstand von Vektor1 zu Vektor2: " << vektor1->sub(vektor1, vektor2) << endl; cout << "Wir addieren Vektor1 und Vektor2..." << endl; vektor* v3 = vektor::add(vektor1, vektor2); v3->ausgabe(); system("PAUSE"); return EXIT_SUCCESS; }
Noch eine abschließende Frage: Ist das jetzt sauber implementiert und umgesetzt?
Könnte ich anstatt "#include "vektor.h"" auch "class vektor;" schreiben (Steht so im Skript, funktioniert bei mir aber nicht...)?
-
10.06.10 16:51 #13
Moin,
ganz eindeutig: nein
(a) "class vektor;" ist schon mal keine korrekte C/C++-Syntax !
(b) mit "class vektor { ... }" (ganz grob vereinfacht!) definierst Du eine neue Klasse, deren Objekte Du instantiieren kannst.
Hierzu werden ja die Dateien vektor.cpp und vektor.h angelegt
(c) Mit der Include-Anweisung teilst Du dem Compiler mit, das er diese Klasse (den Inhalt dieser Datei) an dieser Stelle in den Code rein compilieren soll !
http://www.imb-jena.de/~gmueller/kur.../c_includ.html
Gruß
Klaus
BTW: was meinst Du mit "Script"? etwa PHP ?Geändert von vfl_freak (10.06.10 um 16:54 Uhr) Grund: Tippfehler .... :-( + BTW
Es ist noch kein Meister vom Himmel gefallen - sonst hätte man schon längst seine Leiche gefunden !!
Falls ich helfen konnte, wäre eine Bewertung oder ein Danke nett ;-)
-------------------------------------------------------------------------------------------------
Ich beantworte keine Fragen per PN !!
Stellt Eure Fragen im Forum - dann haben alle etwas davon !!
-
Ich tippe dazu mal ein paar Zeilen aus meinem Skript ab:
Ich glaube es hat gerade Klack gemacht.Forward Declaration
Wenn Sie in einer Klassendefinition Objekte einer anderen Klasse benutzen wollen, müssen Sie dem Compiler den Typen der Klasse bekannt machen. Dies kann "klasisch" über einen Include der ".h-Datei" erfolgen:
Datei a.h
Code :1 2 3 4
class A { //irgendeine Klasse }
Datei b.h
Code :1 2 3 4 5
#include "a.h" class B { void funktionDieABenutzt(A* objektVonA); }
Diese Vorgehensweise ist zwar richtig, führt aber zu längeren Kompilierzeiten [...]
Eine simplere Methode ist die Methode der Forward-Declaration. Hier bei wird dem Compiler nur gesagt: "Es gibt eine Klasse, die A heißt":
Datei a.h
Code :1 2 3 4
class A { //irgendeine Klasse }
Datei b.h
Nutzen Sie diese Methode so oft wie möglich [...]Code :1 2 3 4 5 6
class A; class B { void funktionDieABenutzt(A* objektVonA); }
Bräuchte ich in der Vektor-Klasse noch eine andere selbst-erstellte Klasse von mir, so könnte ich diese andere Klasse in vektor.h mittels "class Klasse;" einbinden. Richtig?
In der Main-Funktion geht dies jedoch nicht.
Habe ich das nun richtig verstanden?
-
10.06.10 17:46 #15
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
So ungefähr.
Eine Vorwärtsdeklaration macht die Klasse zwar bekannt, die Klasse ist aber noch nicht vollständig definiert.
Man darf von solchen unvollständig definierten Klassen Zeiger erstellen.
Man kann aber weder ein Objekt dieser Klasse anlegen, noch kann man irgendwelche Methoden aufrufen (da diese Informationen noch nicht verfügbar sind).
Wenn du also in irgendeiner Form die Klasse benutzen willst, muß die Klassendefinition bekannt sein.Code cpp:1 2 3
class xyz; xyz* ptr = 0;
GrußIf at first you don't succeed, try again. Then quit. No use being a damn fool about it.
Ähnliche Themen
-
[C++] Impliziter Konvertierungsoperator von int zu eigener Klasse
Von Jellysheep im Forum VisualStudio & MFCAntworten: 2Letzter Beitrag: 09.08.10, 17:54 -
settimeout in eigener klasse auf eine Methode der Klasse
Von user2580 im Forum Javascript & AjaxAntworten: 2Letzter Beitrag: 12.04.09, 16:26 -
Array mit eigener Klasse füllen
Von Hackbard_C im Forum C/C++Antworten: 1Letzter Beitrag: 04.07.07, 13:53 -
Probleme mit eigener Klasse
Von Rene42 im Forum .NET CaféAntworten: 3Letzter Beitrag: 16.02.07, 09:25 -
JPanel in eigener Klasse erstellen..
Von f-zoid im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 3Letzter Beitrag: 05.05.06, 16:55





Zitieren

Login






