Problem mit eigener Klasse und Objekten dieser Klasse

Eroli

Erfahrenes Mitglied
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:

- 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

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"?

In meiner vektor.h hatte ich mir das so gedacht:
C++:
#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
C++:
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.
C++:
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
 
Hi.
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"?
Mit Differenz ist vermutlich der Abstand der Vektoren gemeint. Da mußt du ja nur einen Wert zurückgeben.

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.
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:
C++:
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;
}

Könnt ihr mir eine solide Umsetzung beschreiben?
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.
 
Zuletzt bearbeitet:
Hallo,

den Abstand der 2 Punkte (Differenz?) bekommst du über folgende Formel:

Code:
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
 
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?
 
Man, ich liebe dieses Forum. Ihr seid so verdammt schnell :)

Fangen wir erstmal langsam mit der sub-Funktion an:

Vektor.h
C++:
#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
C++:
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:
passing 'const vektor' as 'this' argument of 'const double vektor::getX()' discards qualifiers
Derselbe Fehler kommt für jede Verwendung von get(X/Y/Z)().

Ich bin jetzt erstmal relativ ratlos...

EDIT: Gibt es eigentlich kein eleganteres ^2
 
Zuletzt bearbeitet:
Und die Fehler:

Derselbe Fehler kommt für jede Verwendung von get(X/Y/Z)().
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):
C++:
class vektor {
...
public:
   double getX() const;
...
};

double vektor::getX() const {
  ...
}
EDIT: Gibt es eigentlich kein eleganteres ^2
Schreib dir doch eine square() Funktion.

Und verwende für die Fehlermeldungen einfach [code]..[/code] Tags, Zitate machen sich nicht so gut beim Zitieren...

Gruß
 
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:

C++:
[...]

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:
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:

C++:
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?

C++:
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;
}
 
Zuletzt bearbeitet:
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:

C++:
[...]

void vektor::getLength() const
{
	std::cout << "Length: " << sqrt(x*x + y*y + z*z) << std::endl;
}
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.
Wenn ich bei der sub-Funktion jedoch ein const dahinter schreiben will, kommt der Fehler:
Code:
non-member function `double sub(const vektor*, const vektor*)' cannot have `const' method qualifier
Wie hast du sub denn nun definiert? Vorhin hattest du es noch als Methode.
Warum ist das so? Warum muss ich das bei manchen Funktionen machen und bei anderen wiederrum nicht?
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.
EDIT: Und wie rufe ich die Funktion jetzt auf? Da sie nicht statisch ist, müsste es doch z.B. so gehen:
Ja.
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?
Ja.

Ich würde sub vermutlich einfach als Top-Level Funktion definieren.

Gruß
 
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.

Oh, ich dachte zuerst die Aufgabenstellung fordert das so, aber da steht:
"Eine Funktion, in der die Länge des Vektors berechnet und zurückgegeben wird."

Du hast also vermutlich recht. Ich ändere das.

Wie hast du sub denn nun definiert? Vorhin hattest du es noch als Methode.

Mittlerweile ist es eine Funktion, die eine Gleitkommazahl zurückgibt (Ausschnitt):
C++:
   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:
C++:
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()));
}

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
C++:
static vektor* add(const vektor*, const vektor*);

Implementation
C++:
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
C++:
vektor* v3 = vektor::add(vektor1, vektor2);

Fehler:
Code:
[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.
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück