static Klassenfunktion
-
Hallo ihr lieben,
ich wollte 2 Klassen definieren: PUNKT und LINE. So sehe das ganze aus:
class PUNKT
{
public:
PUNKT (double xi=0, double yi=0){ //Konstructor
x=xi;
y=yi;
}
PUNKT deltaP(PUNKT basis, PUNKT delta){ //Punktverschiebung
PUNKT temp;
temp.x=basis.x+delta.x;
temp.y=basis.y+delta.y;
return temp;
}double x,y;
};class LINE
{
public:
LINE* line(PUNKT p1, PUNKT p2){
LINE* neuline=new LINE;
neuline->a.x=p1.x;
neuline->a.y=p1.y;
neuline->e.x=p2.x;
neuline->e.y=p2.y;
return neuline;
}void printl (LINE* line){
cout <<"Anfangspunkt: "<<line->a.x<<"/"<<line->a.y;
cout <<" Endpunkt: "<<line->e.x<<"/"<<line->e.y<<endl;
}double linel(LINE* line){
double length;
length=sqrt(sq(line->a.x-line->e.x)+sq(line->a.y-line->e.y));
return length;
}private:
PUNKT a, e;
};Im main() programm hab ich ein Zeiger line1 definiert und über die Klassenfunktion line eine Linie initialisiert, und zwar im Heap-Speicherbereich (weil hier mit new s.h oben)
PUNKT p1(3,4), p2(6,7);
LINE* line1;
line1->line(p1,p2);
Jeztz will ich aber druch printl meine linie auf den bildschrim ausgeben, so hab ich geschrieben:
line1->printl;
Kommt der Fehler: "Member funtion must be called or its address taken in funtion main()"
Wie kann ich jetzt richtig machen? Danke schön
-
Hallo,
a) Bitte benutze CPP Tags.
b) Bitte rücke den Code so ein, dass man ihn auch lesen kann.
c) Verwende mehr Whitespaces. Der Compiler ignoriert die Dinger grundsätzlich, als verwende sie. Das gibt Luft in den Quellcode und macht ihn leserlicher.
d) Du hast keine einzige static Funktion in deinem Beispiel.
e) Wieso löst du es nicht so, wie unten angegeben. Verändert habe ich printl und linel.class PUNKT { public: PUNKT (double xi=0, double yi=0){ //Konstructor x=xi; y=yi; } PUNKT deltaP(PUNKT basis, PUNKT delta){ //Punktverschiebung PUNKT temp; temp.x=basis.x+delta.x; temp.y=basis.y+delta.y; return temp; } double x,y; }; class LINE { public: LINE* line(PUNKT p1, PUNKT p2){ LINE* neuline=new LINE; neuline->a.x=p1.x; neuline->a.y=p1.y; neuline->e.x=p2.x; neuline->e.y=p2.y; return neuline; } void printl(){ cout << "Anfangspunkt: " << a.x << "/" << a.y; cout << " Endpunkt: " << e.x << "/" << e.y << endl; } double linel(){ double length; length = sqrt(sq(a.x - e.x) + sq(a.y - e.y)); return length; } private: PUNKT a, e; }; // Beispiel: PUNKT p1(3,4), p2(6,7); LINE line(p1, p2); line.printl(); // Gibt die Linie aus. double dLength = line.linel(); // ... usw. ...Vielleicht noch ein paar weitere Tipps. Schreibe ruhig Funktionsnamen aus. Also besser line_length, bzw. length, wir wissen ja, vom Objekt, dass es eine Linie ist

Wenn ich zudem das Problem anschaue, hast du ein gutes Tutorial oder Buch, mit welchem du C++ lernen kannst? Wenn nicht, unbedingt zu legen. Ich glaube oft wird hier C++ Primer als Einstiegslektüre empfohlen.Grüssli
-
Hey Ya
Also, du hast da ein, zwei recht seltsame Funktionen in deiner LINE-Klasse. Wäre deine LINE* line(PUNKT p1, PUNKT p2) nicht einfacher als Konstruktor (wie bei PUNKT) gelöst?
Naja, jedenfalls, dein printl-Aufruf klappt drum nicht, weil er gar kein richtiger Aufruf ist. Methoden ohne Paramter müssen mit leeren Klammern aufgerufen werden:
line1->printl();Deine printl-Methode nimmt allerdings Parameter entgegen (was eigentlich unnötig ist, es sei denn, du willst die Methode static machen), also wäre der korrekte Aufruf:
line1->printl(line1)Das ist, wie gesagt, äusserst ungewähnlich. Entweder die Methode static machen (=> LINE::printl(line1)) oder this verwenden:
void printl() { cout <<"Anfangspunkt: "<<a.x<<"/"<<a.y; cout <<" Endpunkt: "<<e.x<<"/"<<e.y<<endl; }Dravere hat dir da ja schon eine recht saubere Vorlage, daher denke ich, sollte das prima klappen
.Beste Grüsse
Kessi
-
Danke schön für die schnelle antworte,
@ Dravere: Danke für deine Tips, Bücher hab ich 2: C++ Programmierung von Breymann Ulrich, C++ für Programmierer von Bause Falko.
@KessiMC : die Funktion line kann nicht durch Konstruktor ersetzt werden, da die LINE selbst Objekte enthählt;
Eine andere Möglichkeit hab ich gefunden: alle Funktionen mit static definieren, dann funktionieren alles einwandfrei. Aber hier hab ich eine Frage: Wie ich gelesen habe, man benutzt static funktion nur im falls, dass man auf eine static Klasssevariable zugreifen möchte. Und noch eine frage: Was ist die Unterschied zwischen normal Funktion in einem Klasse und statische Funktion?, natürlich die Zugriff auf Variable usw..verstehe ich schon, aber wann sollte man eine Funktion als static definiert, wann nicht?. Vielen Dank noch mal, und ich warte auf eure antwort.
Vogel
-
vogel schrieb:
@KessiMC : die Funktion line kann nicht durch Konstruktor ersetzt werden, da die LINE selbst Objekte enthählt;
Was hat die Feststellung mit der Begründung zu tun?
-
vogel schrieb:
Aber hier hab ich eine Frage: Wie ich gelesen habe, man benutzt static funktion nur im falls, dass man auf eine static Klasssevariable zugreifen möchte. Und noch eine frage: Was ist die Unterschied zwischen normal Funktion in einem Klasse und statische Funktion?
Grundsätzlich geht man davon aus das der Standardfall einer Methode (Funktion einer Klasse) der ist, das man in der Methode auf die Instanzbezogenen Elemente zugreift (Sprich, die nicht-statischen Membervariablen, die ja von Instanz zur Instanz unterschiedlich gefüllt sein können).
Statische Methoden sind dann sinnvoll, wenn man keinerlei Zugriff auf Nichtstatische Member/Methoden benötigt.
_________________________ | Statische | Nicht- | | Methode | statische | ______________|___________|_Methode___| | Zugriff auf | | | | - this, | Nein | Ja | | Nicht | | | | statische | | | | Member/ | | | |___Methoden__|___________|___________| | - statische | Ja | Ja | | Member/ | | | |___Methoden__|___________|___________|Kurz gesagt: Eine Statische Methode arbeitet auf Ebene der Klasse, nichts statische Methoden auf Ebene der Objekte.
cu André
-
LordJaxom schrieb:
vogel schrieb:
@KessiMC : die Funktion line kann nicht durch Konstruktor ersetzt werden, da die LINE selbst Objekte enthählt;
Was hat die Feststellung mit der Begründung zu tun?
Garnichts

@Vogel: Les dir ein anständiges C++ Buch durch (z.B. C++ Primer). Und arbeite es wirklich vom Anfang an durch. Konstrukoren dienen zur Initialisierung. Warum sollte ein Konstruktor hier nicht verwendet werden können?
Ganz davon abgesehen ist es eigentlich Ungewöhnlich Klassennamen komplett Groß zu schreiben (das tut man eigentlich bei Makros).
class Punkt { public: Punkt(double x=0.0, double y=0.0) : x(x), // Initialisierungsliste y(y) { // <-- Hier erfolgt keine Initialisierung, sondern eine Zuweisung } Punkt deltaP(Punkt const & basis, Punkt const & delta) // Unnötige Kopien vermeiden { // Alternative zu deiner Schreibweise (Über Konstruktor): return Punkt( basis.x + delta.x, basis.y + delta.y); } double x, y; }; class Linie // Deutsch Englisch mischen? (Punkt/Linie, Point/Line) { public: Linie() : a(), b() { } Linie(Punkt const& p1, Punkt const& p2) : a(p1), b(p2) { } // printl, besser lösen über: // Sprechende Namen wären besser (printl und linel sind einfach nur... wenig aussagekräftig) // - statische Methode mit übergabe der Linie // - externe Funktion (dazü müssten x/y aber entweder Public sein oder eine Getter-Methode existieren). // - nicht-statische Methode ohne Übergabe // Variante1 (printl) void Ausgabe() const // const weil die Methode nichts am Objekt ändert { cout << "Anfangspunkt: " << a.x << "/" << a.y; cout << " Endpunkt: " << e.x << "/" << e.y << endl; } // Variante2 (printl) static void Ausgabe(Linie const & linie) { cout << "Anfangspunkt: " << linie.a.x << "/" << linie.a.y; cout << " Endpunkt: " << linie.e.x << "/" << linie.e.y << endl; } double Laenge() // Vorher linel { return sqrt( fabs(linie->a.x - linie->e.x) + fabs(linie->a.y - linie->e.y)); } private: PUNKT a, e; }; int main() { Punkt p1(3,4); Punkt p2(6,7); Linie linie(p1, p2); linie.Ausgabe(); // Über Variante 1 (non-static) Linie::Ausgabe(linie); // Über Variante 2 (static) }