Konstruktor



  • xxx6 schrieb:

    Ich weiss nicht wie gross m_arraySize ist.
    Wo steht das ?

    Genau die Frage stellt sich der Compiler auch.



  • Ja aber die Header war ja mir so gegeben ?

    Soll ich auch arraySize =10 setzen ?

    In der Aufgabe ist es ja nicht definiert .



  • Was setzt du denn noch auf 10? Steht das im Header? Warum 10? Welche Bedeutung haben die Werte und Variablen? Was ist eigentlich mit m_rectangles? Welchen Zustand soll das erzeugte Objekt haben, nachdem der Konstruktor ausgeführt wurde?



  • EHrlich gesagt weiss ich es auch nicht.
    Ich weiss auch nur die Sachen, die in der Aufgabenstellung stehen 😃



  • Tja, dann hast du wohl ein Problem...



  • Das ist meine CRectangle.h

    /*
     * CRectangle.h
     *
     *  Created on: 05.01.2015
     *      Author: mnl
     */
    
    #ifndef ASCIISCREENSOLUTION_MYCODE_CRECTANGLE_H_
    #define ASCIISCREENSOLUTION_MYCODE_CRECTANGLE_H_
    
    #include <ostream>
    using namespace std;
    
    #include "CPoint.h"
    #include "CScreen.h"
    
    /**
     * Diese Klasse beschreibt ein Rechteck in einem
     * Ganzzahl-Koordinatensystem über die Eigenschaften
     * "untere linke Ecke" und "obere rechte Ecke".
     *
     * Als zusätzliche Eigenschaft hat die Klasse ein Zeichen
     * (char) das bei der graphischen Darstellung als
     * Füllzeichen verwendet wird.
     */
    class CRectangle
    {
    private:
    	/** Die linke untere Ecke. */
    	CPoint m_bottomLeft;
    	/** Die rechte obere Ecke. */
    	CPoint m_topRight;
    	/** Das Füllzeichen für die graphische Darstellung. */
    	char m_fillChar;
    
    public:
    	/**
    	 * Erzeugt ein neues Rechteck mit linker unterer und
    	 * rechter oberer Ecke bei (0,0) und dem angegebenen
    	 * Füllzeichen.
    	 */
    	CRectangle(char fillChar = '#');
    
    	/**
    	 * Erzeugt ein neues Rechteck mit der angegebenen linken
    	 * unteren und rechten oberen Ecken sowie dem angegebenen
    	 * Füllzeichen.
    	 *
    	 * Beim Erzeugen wird die Zusicherung überprüft, dass die
    	 * rechte obere Ecke rechts von und oberhalt der linken
    	 * unteren Ecke liegen muss! Falls die x-Koordinate
    	 * der rechten oberen Ecke nicht größer als die x-Koordinate
    	 * der linken unteren Ecke ist, wird sie auf den Wert
    	 * der x-Koordinate der linken unteren Ecke gesetzt. Falls
    	 * die y-Koordinate der rechten oberen Ecke nicht größer als
    	 * die y-Koordinate der linken unteren Ecke ist, wird sie auf
    	 * dem Wert der y-Koordinate der linken unteren Ecke gesetzt.
    	 */
    	CRectangle(CPoint bottomLeft, CPoint topRight, char fillChar = '#');
    
    	/**
    	 * Weist den Eigenschaften "linke untere Ecke" und "rechte obere
    	 * Ecke" neue Werte zu.
    	 *
    	 * Vor der Zuweisung wird die Zusicherung überprüft, dass die
    	 * rechte obere Ecke rechts von und oberhalt der linken
    	 * unteren Ecke liegen muss! Ist das nicht der Fall wird keines
    	 * der Attribute verändert.
    	 */
    	void setCorners (CPoint bottomLeft, CPoint topRight);
    
    	/**
    	 * Liefert die linke untere Ecke des Rechtecks zurück.
    	 */
    	CPoint getBottomLeftCorner() const;
    
    	/**
    	 * Liefert die rechte obere Ecke des Rechtecks zurück.
    	 */
    	CPoint getTopRightCorner() const;
    
    	/**
    	 * Weist dem Füllzeichen den angegebene Wert zu.
    	 */
    	void setFillChar(char fillChar = '#');
    
    	/**
    	 * Liefert den Wert des Füllzeichens.
    	 */
    	char getFillChar() const;
    
    	/**
    	 * Prüft, ob die beiden Rechtecke in allen Eigenschaften übereinstimmen.
    	 */
    	bool operator== (const CRectangle& other) const;
    
    	/**
    	 * Zeichnet das Rechteck in das übergebene Bildschirmobjekt. Das heisst,
    	 * es werden mit CScreen::setPoint die Werte aller "Punkte", die im
    	 * Bereich des Rechtecks liegen, auf das Füllzeichen des Rechtecks gesetzt.
    	 */
    	void draw(CScreen& screen) const;
    
    	/**
    	 * Gibt eine textuelle Darstellung des Rechtecks auf dem übergebenen
    	 * Ausgabestrom aus. Das Format ist in der Aufgabenstellung beschrieben.
    	 */
    	friend ostream& operator<< (ostream& lhs, const CRectangle& rhs);
    };
    
    #endif /* ASCIISCREENSOLUTION_MYCODE_CRECTANGLE_H_ */
    

    implemetierte cpp

    /*
     * CRectangle.cpp
     *
     *  Created on: 05.02.2015
     *      Author: lipp
     */
    
    #include "CRectangle.h"
    #include "CPoint.h"
    CRectangle::CRectangle(char fillChar)
    
    {
      m_fillChar = fillChar;
      /**
         * Erzeugt ein neues Rechteck mit der angegebenen linken
         * unteren und rechten oberen Ecken sowie dem angegebenen
         * F�llzeichen.
         *
         * Beim Erzeugen wird die Zusicherung �berpr�ft, dass die
         * rechte obere Ecke rechts von und oberhalt der linken
         * unteren Ecke liegen muss! Falls die x-Koordinate
         * der rechten oberen Ecke nicht gr��er als die x-Koordinate
         * der linken unteren Ecke ist, wird sie auf den Wert
         * der x-Koordinate der linken unteren Ecke gesetzt. Falls
         * die y-Koordinate der rechten oberen Ecke nicht gr��er als
         * die y-Koordinate der linken unteren Ecke ist, wird sie auf
         * dem Wert der y-Koordinate der linken unteren Ecke gesetzt.
         */
    
    }
    
    CRectangle::CRectangle(CPoint bottomLeft, CPoint topRight, char fillChar)
    {
    	m_fillChar = fillChar;
    	m_bottomLeft = bottomLeft;
    	m_topRight = topRight;
    
    	 if(topRight.getX() < bottomLeft.getX() ){
    
    	    m_topRight.CPoint::setX(bottomLeft.getX());
    	  }
    
    	  if(topRight.getY() < bottomLeft.getY()){
    
    	    m_topRight.setY(bottomLeft.getY());
    	  }
    }
    
    void CRectangle::setCorners(CPoint bottomLeft, CPoint topRight)
    {
    	if(topRight.getX()> bottomLeft.getX() && topRight.getY()> bottomLeft.getY()){
    
    		m_bottomLeft = bottomLeft;
    		m_topRight = topRight;
    	}
    }
    
    CPoint CRectangle::getBottomLeftCorner() const
    {
    	// Bitte implementieren und dabei das return-Statement ersetzen.
    	return m_bottomLeft;
    }
    
    CPoint CRectangle::getTopRightCorner() const
    {
    	// Bitte implementieren und dabei das return-Statement ersetzen.
    	return m_topRight;
    }
    
    void CRectangle::setFillChar(char fillChar)
    {
    	// Bitte implementieren
    	m_fillChar = fillChar;
    }
    
    char CRectangle::getFillChar() const
    {
    	// Bitte implementieren und dabei das return-Statement ersetzen.
    	return m_fillChar;
    }
    
    bool CRectangle::operator ==(const CRectangle& other) const
    {
    	return m_topRight == other.m_topRight &&  m_bottomLeft == other.m_bottomLeft &&m_fillChar == other.m_fillChar;
    }
    
    void CRectangle::draw(CScreen& screen) const
    {
        for(int j = m_bottomLeft.getX(); m_topRight.getX()>=j;j++){
    
    	for(int i = m_bottomLeft.getY();  m_topRight.getY()>=i; i++) {
    	    screen.setPoint(CPoint(j , i),m_fillChar);
    
    	}
        }
    }
    ostream& operator<< (ostream& lhs, const CRectangle& rhs){
    	lhs << "CRectangle[(" << rhs.getBottomLeftCorner().getX() << "," << " " << rhs.getBottomLeftCorner().getY() << ")" << "," << "(" << rhs.getTopRightCorner().getX() << " , "<< rhs.getTopRightCorner().getY()<< " )"<< ","<< " fillChar";
    
    return lhs;
    

    Hilft das weiter ?

    Ich dachte aber das der Konstruktor mit diesem Aufgabenteil nichts zu tun hatte?



  • Hilft das weiter ?

    Es würde dir weiterhelfen, wenn du über die Fragen nachdenkst. Ich werde deine Aufgabe nicht lösen.



  • xxx6 schrieb:

    EHrlich gesagt weiss ich es auch nicht.
    Ich weiss auch nur die Sachen, die in der Aufgabenstellung stehen 😃

    Was könnte den wohl mit ArraySize gemeint sein...



  • Die grösse eines Arrays [n+1];

    Oder halt 10?



  • xxx6 schrieb:

    Die grösse eines Arrays [n+1];

    Was soll das +1?



  • Genau, die größe des aktuellen Arrays. Das soll nur 10 entsprichen, wenn der Konstruktor ohne Parameter aufgerufen wird, oder eben mit 10 als Parameter.

    Aber verwechsel nicht größe eines Arrays und Zugriff Index, siehe Manni66s Post.



  • Da ich jetzt weiss das dass ArraySize =10 ist habe ich die Zusicherung ein wenig
    umgeändert .

    Ich habe auch Speicher angelegt und mit delete freigegeben .
    War mir beim Speicher anlegen nicht ganz sicher ,da in Büchern hauptsächlich erklärt wie Speicher angelegt wird wenn das *Zeichen bei z.B m_rectangles steht.

    Habe es aber trotzdem versucht :

    #include "CDrawing.h"
    #include <ostream>
    using namespace std;
    CDrawing::CDrawing(int initialSize)
    {
        if(initialSize>0 && initialSize <=10){
    
            m_initialSize = initialSize;
        }
        else{
            m_initialSize = 10;
        }
        if(0<= m_nextFree <= m_arraySize){
    
            m_nextFree= nextFree;
        }
        else{
    
            m_nextFree=0;
        }
        if(m_arraySize>0 && m_arraySize <=10){
            m_arraySize= arraySize;
        }
    
        CRectangle* m_rectangles = new CRectangle;
    }
    
    CDrawing::~CDrawing()
    {
        delete[] m_rectangles;
    }
    

    Ist der Speicher so richtig angelegt?



  • xxx6 schrieb:

    Ist der Speicher so richtig angelegt?

    Nein, du musst auch die Größe übergeben.

    Ich habe den Thread jetzt nur so überflogen, daher: muss das in diesem veralteten Stil sein? Ansonsten std::vector (wobei ich wetten würde, dass dieser Hinweis in einem dreiseitigen Anfänger-Problem-Thread schon gegeben wurde)



  • Mit Grösse wäre es ja so:

    CRectangle* m_rectangles = new CRectangle[10];
    

    Wir haben nur eine einführung in Programmierung ,daher kein Vector behandelt.

    Wieso soll man beim Speicher allokieren noch die Grösse dazu schreiben ?
    Das stand z.B in Büchern nicht drinnen .

    Woher soll ich das wissen?



  • So, warum nicht

    m_arraySize = initialSize;
    

    Wenn du new keine größe mit gibst, reservierst du Speicher für ein Element. Dass ist nicht was du willst. Steht sehr sicher in jedem c++ Buch. Sonst in der Dokumentation.

    Außerdem gehört zu new ein delete, kein delete[].
    delete[] gehört zu new []

    Was du wahrscheinlich haben wolltest ist sowas:

    m_rectangles = new CRectangle[m_arraySize] ;
    


  • Wie sieht es eigentlich mit meinem Konstruktor aus Leute ?
    Ich meine in der Aufgabe ist ja kaum gesagt worden was die überhaupt wollen ?



  • Es ist offensichtlich was gefordert ist.



  • Oder anders gesagt, dein Konstruktor entspricht nicht den Anforderungen.



  • Was fehlt genau an meinem Konstruktor ?

    Es ist nur ne Ünungsaufgabeb



  • Der ist einfach nur falsch. Sinn des Konstruktors ist es anhand der übergebenen Parameter die Klassenmember korrekt zu initialisieren.
    Also bei deinem Code aus initialSize die beiden Member m_rectangles und m_arraySize zu setzen (m_nextFree ist ja schon über die Klassendeklaration im Header auf 0 gesetzt).

    Die (erste) Lösung sieht also so aus:

    CDrawing::CDrawing(int initialSize)
    {
        m_arraySize = initialSize;
        m_rectangles = new CRectangle[initialSize];
    }
    

    Für die Initialisierung gibt es aber explizit noch die Initialisierungsliste bei den Konstruktoren, so daß die Lösung dann so lautet:

    CDrawing::CDrawing(int initialSize)
     : m_arraySize(initialSize), m_rectangles(new CRectangle[initialSize])
    {
    }
    

    In gutem (professionellen) C++ Code würde man aber dann stattdessen std::vector<> benutzen.

    Und auf die ungarische Notation ("C" am Anfang des Klassennamens) solltest du auch zukünftig verzichten.

    PS: Die Schreibweise

    CDrawing(int initialSize = 10);
    

    im Header bedeutet nur, daß 10 der Vorgabewert (default value) ist, wenn man beim Aufruf keinen Parameter angibt, also

    CDrawing drawing;
    

    So wird der Konstruktor mit 10 als initialSize aufgerufen (innerhalb des Konstruktorcodes kann dir das aber egal sein und muß nicht explizit darauf geprüft werden).


Anmelden zum Antworten