Konstruktor Problem



  • Hallo,

    ich lerne für mein Studium gerade die Anfänge von C++ und stehe nun vor einem Problem, für das ich keine Lösung weiß. Der Compiler erzeugt mir eine Fehlermeldung an der Stelle wo ich in main ein Objekt erzeuge und Werte zuweise. (PERSON p("Mueller", "Peter", 33))

    Hier der Code:

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    class PERSON
    { 
        private:
        string vorname, name;
        int  alter;  
        public:
        PERSON& operator  = (const PERSON& einePerson)
                { 
                  name    = einePerson.name;
                  vorname = einePerson.vorname;
                  alter   = einePerson.alter;
                  return *this;
                }
    
    };
    
    int main()
    {
        PERSON p("Mueller", "Peter", 33);
    
      system("Pause");
      return EXIT_SUCCESS;
    
    }
    


  • Du brauchst einen Kosntruktor Person::Person(string, string, int)



  • Danke dir!

    Wo setze ich ihn in den Code ein?



  • class PERSON
    {
        public:
            PERSON(const string &strName, const string &strVorname, int nAge)
            :    name(strName),
                 vorname(strVorname),
                 alter(nAge)
            { }
    
    // rest wie gehabt
    };
    


  • deklaration in die klasse und definition ausserhalb:
    oder komplett mit initialisierungsliste in die klasse

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    class PERSON
    {
        private:
        string vorname, name;
        int  alter;  
        public:
        PERSON(const string & nam, const string & vornam, const int alt):
        name(nam),vorname(vornam),alter(alt){}
        PERSON& operator  = (const PERSON& einePerson)
                {
                  name    = einePerson.name;
                  vorname = einePerson.vorname;
                  alter   = einePerson.alter;
                  return *this;
                }
    
    };
    
    int main()
    {
        PERSON p("Mueller", "Peter", 33);
    
      system("Pause");
      return EXIT_SUCCESS;
    
    }
    


  • Nochmals Danke euch zweien!

    Ich habe mein Fehler verstanden, und kann jetzt auch die Compliler-Fehlermeldung deuten!

    Jorgo



  • Jetzt habe ich aber doch noch eine Frage:

    Ist dann nicht der ganze Bereich mit

    PERSON& operator  = (const PERSON& einePerson)
                { 
                  name    = einePerson.name;
                  vorname = einePerson.vorname;
                  alter   = einePerson.alter;
                  return *this;
                }
    

    unnötig? Schließlich übergebe ich ja die Werte an:

    PERSON(const string &nam, const string &vornam, const int alt): 
        name(nam),vorname(vornam),alter(alt){}
    


  • Den brauchst du für Copy-Zuweisung, zB. PERSON a( "Foo", "bar", 12 ), b( "Bla", "blubb", 13); a = b; // a hat nun den gleichen Inhalt wie b, aber ne eigene Kopie davon



  • kommt darauf an, ob du eine zuweisung zulassen möchtest

    PERSON p("müller", "peter", 33);
    PERSON p1;
    p1 = p;
    

    somit wäre p1 == p, was natürlich keinen sinn macht 😃

    am besten du liesst noch ein bisschen
    http://tutorial.schornboeck.net/bigthree.htm
    http://www.cpp-tutor.de/cpp/le12/le12_03.htm



  • User--- schrieb:

    Den brauchst du für Copy-Zuweisung, zB. PERSON a( "Foo", "bar", 12 ), b( "Bla", "blubb", 13); a = b; // a hat nun den gleichen Inhalt wie b, aber ne eigene Kopie davon

    Verstehe! So in der Art?:

    int main()
    {
        PERSON p("Mueller", "Peter", 33);
        PERSON q("Bla", "blubb", 13); 
        q = p;   
    
    cout<<p.get_name()<<endl;
    cout<<q.get_name()<<endl;
    


  • Aber wie mache ich es dann wenn ich nur den Vorname und das Alter kopieren möchte?

    PERSON p("Mueller", "Peter", 33);
        PERSON q("Bla"); 
        q = p;
    




  • miller_m schrieb:

    http://www.cpp-tutor.de/cpp/le12/le12_03.htm#mehrfach

    OK, ich lese mich nochmals durch. Danke für die Geduld!

    Viele Grüße
    Jorgo



  • Geht auch per default-Parameter - etwa so:

    PERSON::PERSON (const char *szName,
                    const char *szFirstName = NULL,
                    const char  iAge = (-1))
    {
        bool    fSuccess;
    
        SetDefaultValues ();            //Noch zu schreiben!
    
        fSuccess = SetName (szName);    //Noch zu schreiben!
    
        if ((fSuccess == true) && (szFirstName != NULL))
            fSuccess = SetFirstName (szFirstName) //Noch zu schreiben!
    
        if ((fSuccess == true) && (iAge > 0))
            fSuccess = SetAge (iAge);   //Noch zu schreiben!
    
        if (fSuccess == false)
            throw (1);                 //Nummer/Mssg/Type 
                                       //(statt 1) noch definieren! 
    }
    


  • Wir sind hier in nem C++-Forum 🙄



  • ... schrieb:

    Wir sind hier in nem C++-Forum 🙄

    Das stimmt, aber manchmal ist es sinnvoll, einen NULL-Pointer als Marker fuer etwas zu nehmen. Die Transformation in die std::string-Klasse kann dann in den Set-Methoden erfolgen. Wo "C-Style" angemessen oder einfach schneller oder einfacher nehme ich ihn auch.



  • MBCS-CITP schrieb:

    Geht auch per default-Parameter - etwa so:

    PERSON::PERSON (const char *szName,
                    const char *szFirstName = NULL,
                    const char  iAge = (-1))
    {
        bool    fSuccess;
    
        SetDefaultValues ();            //Noch zu schreiben!
    
        fSuccess = SetName (szName);    //Noch zu schreiben!
    
        if ((fSuccess == true) && (szFirstName != NULL))
            fSuccess = SetFirstName (szFirstName) //Noch zu schreiben!
    
        if ((fSuccess == true) && (iAge > 0))
            fSuccess = SetAge (iAge);   //Noch zu schreiben!
    
        if (fSuccess == false)
            throw (1);                 //Nummer/Mssg/Type 
                                       //(statt 1) noch definieren! 
    }
    

    ahh...lol...sorry...is mir nur so rausgerutscht

    PERSON::PERSON (const std::string& name,
                    const std::string& vorname=std::string(),
                    const char  alter = 0)
                    :name(name),vorname(vorname),alter(alter)
    

    so von wegen schneller...

    @Jorgo das ist so nicht ohne weitere möglich-zumindest nicht mit dem zuweisungsoperator. Der zuweisungsoperator ist dazu da, komplett zu kopieren, und nicht nur Teilstücke. Wär ja fast so, wie wenn dir beim zuweisen von int werten nur das erste Bit kopiert werden würde 😃

    wenn du aber zb nur den namen doer nur das alter kopieren willst, kannst du natürlich auch funktionen für sowas schreiben:

    PERSON p("Mueller");
    PERSON q("Bla");
    
    p.setVorname("Peter");
    p.setAlter(33);
    
    q.setVorname(p.getVorname());
    q.setAlter(p.getAlter());
    


  • @otze

    Nur muss man zwischen zwei Dingen unterscheiden: Zwischen einem nicht gesetzten Datentyp und einem leeren: Es ist ein Unterchied, ob ich einen String vom Default Konstruktor der Stringklasse, der leer ist (also nur ein End-of-String") enthalte oder ob ich den entsprenden Wert garnicht gesetzt habe. Dies kann man am einfachsten einen NULL-Pointer setzen. Ansosnten haette ich dort keine Moeglichkeit, ausser einem Extra-Flag.



  • MBCS-CITP schrieb:

    @otze

    Nur muss man zwischen zwei Dingen unterscheiden: Zwischen einem nicht gesetzten Datentyp und einem leeren: Es ist ein Unterchied, ob ich einen String vom Default Konstruktor der Stringklasse, der leer ist (also nur ein End-of-String") enthalte oder ob ich den entsprenden Wert garnicht gesetzt habe. Dies kann man am einfachsten einen NULL-Pointer setzen. Ansosnten haette ich dort keine Moeglichkeit, ausser einem Extra-Flag.

    was ist NULL sonst ?

    void myfunc(int i){cout << i << endl;}
    void myfunc(void* vp){cout << "void pointer" << endl;}
    ...
    myfunc(NULL);
    

    Na was wird aufgerufen ? 🙄



  • MBCS-CITP schrieb:

    @otze

    Nur muss man zwischen zwei Dingen unterscheiden: Zwischen einem nicht gesetzten Datentyp und einem leeren: Es ist ein Unterchied, ob ich einen String vom Default Konstruktor der Stringklasse, der leer ist (also nur ein End-of-String") enthalte oder ob ich den entsprenden Wert garnicht gesetzt habe.

    es gibt in C++ keinen leeren Datentyp. du hast auch nicht die möglichkeit eine variable nicht zu setzen, da immer zuerst der default-ctor aufgerufen wird. Das Ergebnis kann zwar undefiniert sein, wie zb bei integer werten, die zu dem zeitpunkt jeden wert haben können, aber der default ctor wird aufgerufen.
    Ausnahme ist natürlich, du benutzt eine initialisierungsliste, dann wird der default ctor durch den ersetzt, den du in der initialisierungsliste angegeben hast.



  • otze schrieb:

    es gibt in C++ keinen leeren Datentyp. du hast auch nicht die möglichkeit eine variable nicht zu setzen, da immer zuerst der default-ctor aufgerufen wird.

    Das ist das Problem. Deshalb habe ich angewoehnt, grundsaetzlich in solchen Faellen Memberklassen nur als Pointer zu einer Instanz der Klasse auftauchen zu lassen, die im Default-Konsturktor auf NULL gesetzt wird und ggf. waerend der Lebenszeit des Objects durch einen new-Operator der Memberklasse mit "Leben" gefuellt wird.


Anmelden zum Antworten