Definieren einer Methode außerhalb der Klasse



  • Hallo,

    ich schreibe kommende Woche meine Prüfung in Programmierung 1 und hab eine paar Fragen zu einer früheren Klausuraufgabe, ich hoffe ihr könnt mir helfen!

    Zur Ausgangslage:

    Die Klasse „rechteck“ besitzt folgende Eigenschaften:
    -zwei private Variablen (Typ float) für die Attribute „laenge“ und „breite“
    -eine private Klassenvariable zum Zählen der generierten Instanzen (Rechtecke)

    Die Klasse soll folgende Methoden (public) zur Verfügung stellen:
    (1)einen Standardkonstruktor zur Initialisierung der Attribute „laenge“ und „breite“ mit 0
    (2)einen Konstruktor mit zwei float-Parametern zum Setzen der Attribute „laenge“ und „breite“
    (3)eine Methode „flaeche“, die die Fläche eines Rechtecks errechnet und auf dem Bildschirm ausgibt
    (4)eine Klassenmethode „anzahl_rechtecke“, die die Anzahl der generierten Instanzen (Rechtecke) auf dem Bildschirm ausgibt.

    Frage: Definieren Sie nun die Methode (2) aus der Ausgangslage außerhalb der Klasse „rechteck“
    (einen Konstruktor mit zwei float-Parametern zum Setzen der Attribute „laenge“ und „breite“)

    Wie kann ich das lösen, was muss ich da schreiben?

    Für eure Hilfe bin ich echt sehr dankbar!



  • Hallo,

    was hast Du denn schon? Weißt Du grundsätzlich, wie man eine Klasse definiert?



  • So sieht die Ausgangslage aus...

    #include <iostream>
    
    class rechteck
    {
    	float laenge,breite,inst_cnt;
    public:
    	rechteck(void)
    	{
    		laenge=0; breite=0;
    	}
    	rechteck(float,float);
    	void flaeche(void)
    	{
    		std::cout<<laenge*breite;
    	}
    	void anzahl_rechtecke(void)
    	{
    		std::cout<<inst_cnt;
    	}
    }
    

    ...und das ist die Antwort auf die Frage:

    rechteck::rechteck(float laenge_init,float breite_init)
    {
    	laenge=laenge_init; breite=breite_init;
    }
    


  • Hallo,

    danke erstmal für die Antwort.

    ich hab ein Beispiel wie ich das gemacht hätte, vielleicht könnt ihr mal drüberschauen ob das so stimmt:

    class rechteck
    {
    public:
    rechteck(float a = 0, float b = 0);

    float laenge;
    float breite;

    float flaeche();
    int anzahl_rechtecke();
    };

    rechteck::rechteck(float a, float b)
    {
    laenge = a;
    breite = b;
    anz_rechtecke++;
    }

    float rechteck::flaeche()
    {
    return laenge * breite;
    }

    int rechteck::anzahl_rechtecke()
    {
    return anz_rechtecke;
    }

    Ist das soweit in Ordnung?



  • Hallo

    Probier es doch aus. Wenn du willst das sich jemand das anschauet dann solltest du es lesbarer formatieren : sfds

    bis bald
    akari



  • fm2008 schrieb:

    ich hab ein Beispiel wie ich das gemacht hätte, vielleicht könnt ihr mal drüberschauen ob das so stimmt:

    class rechteck
    {
    public:
        rechteck(float a = 0, float b = 0);
    
        float laenge;
        float breite;
    
        float flaeche();
        int anzahl_rechtecke();
    };
    

    Da Du bei den Seiten des Rechtecks immer von Länge und Breite sprichst, solltest Du die Variabalen auch immer so nennen. Die Attribute der Klasse sollten private sein. Und die Methode anzahl_rechtecke sollte static sei, da sie alle (!) Rechtecke betrifft, also global ist.
    Die Methode flaeche sollte const sein, da sie ein Rechteck-Objekt nicht verändert.

    Verbesserungsvorschlag:

    class rechteck
    {
    public:
        rechteck(float laenge_ = 0, float breite_ = 0);
    
        float flaeche() const; 
        static int anzahl_rechtecke();
    private:
        float laenge;
        float breite;
        static int anz_rechtecke;
    };
    

    Benutze bei der Implementierung des Konstruktors Initialisierungslisten.

    Gruß
    Werner



  • akari, hier wie von dir gewünscht, und ich habs geschafft 🙂 danke für den Hinweis mit dem Syntaxcoloring, ich wusst nicht wie das geht...

    class rechteck
    {
    public:rechteck(float a=0, float b=0);
    
    float laenge;
    float breite;
    
    float flaeche();
    int anzahl_rechtecke();
    }
    reckteck::rechteck(float a, float b)
    {
    laenge=a;
    breite=b;
    anzahl_rechtecke++;
    }
    float rechteck::flaeche()
    {
    return laenge*breite;
    }
    int rechteck::anzahl_rechtecke()
    {
    return anzahl_rechtecke;
    }
    

    Danke Werner für deinen Verbesserungsvorschlag! aber wie muss ich es unten abändern, wenn ich nicht mehr a und b sondern "laenge" und "breite" habe?
    Könntest du dein Beispiel fortführen und mir das mit dem Konstruktur zeigen und wie ich dann die Attribte "laenge" und "breite" setzen kann?

    Vielen Dank für eure Hilfe, ich hoffe ich strapazier eure Nerven nicht allzusehr.



  • class rect
    {
        float m_length;
        float m_width;
        static unsigned int ms_count;
    
    public:
        rect(float length = 0.f, float width = 0.f)
            : m_length(length), m_width(width)
        { ++rect::ms_count; }
        ~rect()
        { --rect::ms_count; }
    
    public:
        float area() const { return width * length; }
        static int count() { return ms_count; }
    };
    
    rect::ms_count(0);
    

    so sehe das aus, wenn du es mit width und length machen würdest 😉 Und dann gibt dir count auch die korrekte Anzahl!



  • Ich hab hier nochmal einen Lösungsansatz, ein bisschen anders als oben dargestellt. Könnt ihr euch das ansehen und mir sagen ob das so in Ordnung ist, und der aufgabenstellung entspricht, eine Methode zum setzen der Attribute "laenge" und "breite" zu entwerfen?

    Danke

    class rechteck 
    { 
    public: 
       rechteck(float laenge = 0, float breite = 0); 
       ~rechteck(); 
    
       float flaeche(); 
       static int anzahl_rechtecke(); 
    
    private: 
       float laenge; 
       float breite; 
       static int anzahl_rechtecke; 
    }; 
    
    int rechteck::anzahl_rechtecke = 0; 
    
    rechteck::rechteck(float a, float b) 
    { 
    
       laenge = a; 
       breite = b; 
    
       anzahl_rechtecke++; 
    } 
    
    rechteck::~rechteck() 
    { 
    
       anzahl_rechtecke--; 
    } 
    
    float rechteck::flaeche() 
    { 
       return laenge*breite; 
    } 
    
    float rechteck::anzahl_rechtecke() 
    { 
       return anzahl_rechtecke; 
    }
    

    Danke für eure Hilfe!



  • * Die Aufgabenstellung (1 + 2) verlangt von dir zwei Konstruktoren
    * Die Aufgabenstellung (3) ist nur teilerfüllt. Du berechnest zwar den Flächeninhalt, führst aber keine Ausgabe durch.
    * Die Rückgabe der Anzahl der Instanzen sollte als Aufzähltyp (Ganzzahl, idealerweise size_t) erfolgen, nicht als Fließkommazahl.

    Initialisierungslisten sind auch eine feine Sache:

    rechteck::rechteck()
        : laenge(0.0f), breite(0.0f)
        {
            ++instances;
        }
    
    rechteck::rechteck(float laenge, float breite)
        : laenge(laenge), breite(breite)
        {
            ++instances;
        }
    

    In dem Zusammenhang weise ich aber mal auf ein altes Problem hin, was mir schon drei graue Haare beschert hat: http://www.c-plusplus.net/forum/viewtopic-var-t-is-196486

    Grüße... Heiko



  • Man kann einen Konstruktor mit Default-Parametern als 2 Konstruktoren betrachten.


  • Mod

    (D)Evil schrieb:

    Man kann einen Konstruktor mit Default-Parametern als 2 Konstruktoren betrachten.

    Es sind sogar 3. Dieser Konstruktor konvertiert auch floats direkt und implizit - zudem ist das Ergebnis nicht besonders sinnvoll. Schließlich wird man in den meisten Fällen keine Verwendung für ein Rechteck mit Länge aber ohne Breite haben - jedenfalls nicht als Standard.



  • @fm2008: Sind die klassen von dir selber geschrieben , oder hast irgendwo abgeschrieben?


Anmelden zum Antworten