Objektorientierte Programmierung - Methodenaufruf



  • Hallo,
    ich habe eine Klasse Fahrzeuge definiert und möchte diese über eine Methode der Klasse aufrufen. Nun streikt der Compiler an der Aufrufstelle(Zeile 43) mit der Meldung (Keine Instanz von überladener Funktion "to_string" stimmt mit der Argumentliste überein. Ich sehe das Problem leider nicht und hoffe, ihr könnt mir da weiterhelfen.
    Außerdem habe ich erst vor einigen Tagen mit der OOP angefangen und hätte noch einige Fragen:
    1)Der Konstruktor ist ja eine spezielle Methode zur Objekterzeugung und Initialisierung. Wenn der Konstruktor keine Defaultwerte erhält, muss dann ein Default Konstruktor noch davor stehen?
    2) Ist mein Konstruktor richtig? 😃 oder könnte man das auch anders machen?
    3)getter und setter sind ja für einen kontrollierten Zugriff auf die private geschützen Attribute da. Brauche ich diese aber, wenn ich bereits einen Konstruktor habe? Wenn ja, wozu genau benötige ich Getter und Setter neben dem Konstruktor?

    Hier der Code:

    class Fahrzeug {
    private:
    string marke;
    int preis, kilometer;
    public:
    // Konstruktor
    Fahrzeug(); // Default
    Fahrzeug(string m, int p, int k) : marke{ m }, preis{ p }, kilometer{ k } {};
    
    //getter und setter
    string get_marke() const {
    	return marke;
    }
    void set_marke(string m)
    {
    	this->marke = marke;
    }
    int get_preis()const {
    	return preis;
    }
    void set_presi(int p)
    {
    	this->preis = preis;
    }
    int get_kilometer()const {
    	return kilometer;
    }
    void set_kilometer(int k) {
    	this->kilometer = kilometer;
    }
    
    string to_string(string marke, int preis, int kilometer) const{
    	return marke + " (" + std::to_string(preis) + " €) Kilometerstand: " + std::to_string(kilometer);
    }
    
    };
    
    
     int main()
     {
    Fahrzeug f1 = { "BMW",50000, 100000 };
    
    to_string(f1);
    
    
    system("PAUSE");
    return 0;
    

    }


  • Mod

    Was sollte denn deiner Meinung nach bei to_string(f1); aufgerufen werden? Die Memberfunktion aus Zeile 32? Wie soll das passen?

    1. Nein, nicht zwingenderweise. Da deine Klasse aber keine Funktionalität hat, sondern eine reine Datenhalde ist, wäre es übliches Design, dass man eine Art von Leerinitialisierung anbietet.
    2. Ja, aber schwer lesbar. C++ ist kein Wettbewerb um unverständliche Parameternamen. Frag mal jemanden auf der Straße, was er mit m, p, oder k verbindet, wenn von Fahrzeugen die Rede ist.
    3. Es besteht absolut kein Zusammenhang zwischen Konstruktoren, Gettern, oder Settern. Keines davon impliziert irgendwie die Existenz oder nicht-Existenz der jeweils anderen.


  • Außerdem habe ich eine Subklasse von Fahrzeug (das Attribut hier macht 0 sinn, ich weiß) und würde gerne wissen, wie ich die to_string methode richrig definiere, denn hier stimmem wieder die Argumente nicht Zeile14 (sind zu wenige)

     class Auto :Fahrzeug {
     private: 
    int plaetze;
    public:
    Auto(int pl) :plaetze(pl) {};
    int get_plaetze()const {
    	return plaetze;
    }
    void set_plaetze(int plaetze) {
    	this->plaetze = plaetze;
    }
    
    string to_string()const {
    	return Fahrzeug::to_string(string m, int p, int k) + "Plaetze: " + std::to_string(plaetze);
    }
    };


  • @SeppJ

    1. Mir ist nur aufgefallen, dass der Compiler ohne Default Konstruktor eine Fehlermeldung bezüglich dessen ausgespuckt hat.
    2. Ja das stimmt die Variablen sind jetzt nicht besonders aussagekräfitg
    3. wenn der Konstruktor für die objekterzeugung und initialisierung verantwortlich ist, was machen dann die getter und setter? Ich habe gelernt, dass wir durch getter und setter zugriff auf die private Attribute der Klasse auch außerhalb der klasse haben können. Aber macht der Konstruktor das im Prinzip nicht auch?

    und zu dem Hauptfehler:
    ich weiß nicht, wie ich diese Methde sonst aufrufen soll. So kenne ich das eigentlich aus den Funktionen.
    Wenn man zb nur ein Attribut der Klasse aufrufen möchte setzte man objekt.name={...};
    Hab jetzt einfach mal f1.to_string ausprobiert und diese Fehlermeldung ist zumindest weg.
    Jetzt meckert der Compiler aufgrund fehlender Verweise. Aber wozu brauche ich in diesem Fall einen Verweis?
    Ich kenne das nur mit den Verweisen, bei Objekten abgeleiteter Klasse (da diese Mehr Speicherplatz benötigen)
    Bzw hab f1.to_string()
    Problem ich brauche ja ein Argument. Das wäre in diesem Fall f1.
    Aber f1.to_string(f1); funktioniert auch nicht
    Letze mir erdenkliche Möglichkeit wäre
    Fahrzeug.to_string(f1); aber das geht auch nicht 😃

    ***********************************neuer stand ***************************
    habe die Argumenter aus der Methode rausgenommen und jetzt compiliert er, aber er gibt die werte nicht aus
    ich vollidiot... hatte kein cout 😃 nehem alles zurück 😃



  • @mmm_1482_

    void set_kilometer(int k) {
    	this->kilometer = kilometer;
    }
    

    Das macht nichts sinvolles. k wird nicht benutzt!

    Aber macht der Konstruktor das im Prinzip nicht auch?

    Der Konstruktor macht get? Wie oft kannst du einen Wert mit dem Konstruktor ändern?

    Gett/Setter sind im Regelfall Schwachsinn, haben mit OOP nichts zu tun und werden leider allzu oft gelehrt.



  • @SeppJ Kannst du mir bitte noch erklären, wo hier der Fehler liegt? Zeile 23 wird mir als Fehler angezeigt

     class Auto :Fahrzeug {
    private: 
    int plaetze;
    public:
    Auto(int pl) :plaetze(pl) {};
    int get_plaetze()const {
    	return plaetze;
    }
    void set_plaetze(int plaetze) {
    	this->plaetze = plaetze;
    }
    
    string to_string()const {
    	return Fahrzeug::to_string() + "Plaetze: " + std::to_string(plaetze);
    }
    };
    
    
    int main()
    {
    Fahrzeug f1 = { "BMW",50000, 100000 };
    
    Auto p1 = { "BMW",1000, 130000, 5 };
    
    cout<< f1.to_string();
    
    
    system("PAUSE");
    return 0;
    }


  • @mmm_1482_ sagte in Objektorientierte Programmierung - Methodenaufruf:

    Zeile 23 wird mir als Fehler angezeigt

    Copy&Paste! Immer!



  • @manni66 Nein ich meinte nicht, dass der Konstruktor get macht, sondern dass der im Endeffekt beide einen Zugriff auf private deklarierte Attribute erlauben. Und wo da wirklich der Unterschied ist.
    Ja ich hab öfter gelesen, dass getter und setter relativ unnötig sind.. Leider müssen wir das auch können und der Prof definiert zu jeder klasse immer die getter und setter 😃



  • @manni66 Was genau meinst du jetzt damit 😃 also ich brauch ja für den Aufrufer 5 Argumente, oder nicht? Und die sind hier alle gesetzt... aber liegt es eventuell an der Methode?



  • @mmm_1482_ sagte in Objektorientierte Programmierung - Methodenaufruf:

    Und wo da wirklich der Unterschied ist.

    Ich habe nicht den Eindruck, dass du über die Frage ernsthaft nachgedacht hast.



  • @mmm_1482_ sagte in Objektorientierte Programmierung - Methodenaufruf:

    Was genau meinst du jetzt damit

    Du sollst die Fehlermeldung zeigen.



  • @manni66 "Keine Instanz des Konstruktors ""Auto::Auto"" stimmen mit der Argumentliste überein.
    Darumhin habe ich einfach nur den dazukommenden Wert der abgeleitetenklasse gesetzt:
    Auto p1={5};
    Dann war zwar die Fehlermeldung weg, aber dann kommt folgende Fehlermeldung:
    "Verweis auf nicht aufgelöste extrenes Symbol "public:_thiscall Fahrzeug::Fahrzeug (void)" (?? 0Fahrzeug@.......)"



  • @mmm_1482_ Warum hat der Konstruktor von Auto nur einen Parameter? Warum wird der Konstruktior von Fahrzeug nicht ausgerufen?



  • @manni66
    also so gut es ging eben.
    Konstruktoren sind zur erzeugung und Initialisierung von neuen Objekten zuständig. Da durch die Deklaration von private auf die Attribute kein Zugriff außerhalb der Klasse Möglich ist und man somit ohne einen Konstruktor keine neuen Objekte erzeugen und initialisieren kann.
    Und getter und setter (so wurde gesagt) ist für einen kontrollierten Zugriff auf private Attribute, damit man dort die Attribute auch nutzen kann.
    Aber irgendwie ist das für mich dasselbe 😃



  • @mmm_1482_ sagte in Objektorientierte Programmierung - Methodenaufruf:

    Aber irgendwie ist das für mich dasselbe

    Das meinte ich mit nicht ernsthaft nachgedacht!

    std::cout << fahrezeug.get_plaetze();
    

    Wie geht das mit einem Konstruktor?



  • @manni66 weil doch eigentlich nur das Neue Attribut plaetze dazu gekommen ist. Muss ich die Attribute der Basisklasse auch wieder einfügen? ....



  • @mmm_1482_ sagte in Objektorientierte Programmierung - Methodenaufruf:

    Muss ich die Attribute der Basisklasse auch wieder einfügen?

    Natürlich. Du solltest dein Lernmaterial drimgend noch einmal durchgehen.



  • @manni66 hmm okay verstehe.. mit getter kann man werte ausgeben und mit konstruktoren nur Objekte erzeugen und initialisieren?
    Okay hab jetzt nochmal die Unterlagen durchgeschaut und tatsächlich.. ich hab die seite irgendwie übersehen.

    Danke 🙂


Anmelden zum Antworten