Klassenobjekt in einer anderen Klasse erstellen



  • Hallo,

    ich kann nicht beurteilen, ob und wie konfus diese Frage ist. Jedenfalls möchte ich ein Objekt in einer anderen Klasse erstellen. Eigentlich kein Problem, doch diese Klasse hat einen Parameter und schon habe ich keine Ahnung mehr.

    #include <iostream>
    #include <string>
    
    class A
    {
    public:
        A( const std::string& name ) : a_name( name )
        {
            read_something( a_name );
        }
        int getV() const;
    
    private:
        std::string a_name;
        int v = 0;
        void read_something( const std::string& );
    };
    
    int A::getV() const
    {
        return v;
    }
    void A::read_something( const std::string& a_name )
    {
        v = 5; 
    }
    
    ///////////////////////////////////////////////////////
    
    class C
    {
    public:
        A getA() const;
    private:
        A a( "xxx" ); //Wie mache ich das richtig?
    };
    
    A C::getA() const
    {
        return a; //"Wie muss die Rückgabe richtig lauten?
    }
    
    //////////////////////////////////////////////////////////
    
    int main()
    {
        A a( "yyy" );
        int va = a.getV();
    
        C c;
        int vc = c.getA().getV();
    }
    

    Ich möchte neben den regulären Objekten von A noch ein persönliches für C haben.



  • Entweder über die member initializer list oder mit A a{ "xxx" }; .
    Zeile 40 ist richtig. Unter Umständen solltest du aber aus dem Rückgabetyp von getA ein const A& machen. Damit entfällt die Kopie in Fällen wie Zeile 51.



  • Du musst das A im Konstruktor erzeugen:

    class C 
    { 
    public:
        C() : a("xxx") {}
        A getA() const; 
    private: 
        A a;
    };
    

    Zur 2. Frage:

    A C::getA() const 
    { 
        return a; //"Wie muss die Rückgabe richtig lauten? 
    }
    

    Entweder genauso (dann muss es den Copy-Constructor A::A(const A&) geben) oder du gibst einfach anstatt A lieber const A& zurück.



  • Aha, danke schön 🙂

    Und danke für den Tipp, auch den Rückgabetyp const& zu machen. Das kannte ich noch nicht.

    Wie zwei kurze Antworten schon helfen können 😉



  • Ich hätte noch eine kleine Bitte.

    Da ich immer noch this und -> nicht richtig lesen kann, kann jemand wenn möglich bei dem Beispielcode this und/oder -> statt den Punkten ausschreiben?

    #include <string>
    
    class A
    {
    public:
        A( const std::string& name ) : a_name( name )
        {
            read_something( a_name );
        }
        int getV() const;
    
    private:
        std::string a_name;
        int v = 0;
        void read_something( const std::string& );
    };
    
    int A::getV() const
    {
        return v;
    }
    void A::read_something( const std::string& a_name )
    {
        v = 5;
    }
    
    ///////////////////////////////////////////////////////
    
    class C
    {
    public:
        C() : a( "xxx" ){}
        const A& getA( const std::string& ) const;
    private:
        A a;
    };
    
    const A& C::getA( const std::string& name ) const
    {
        return a;
    }
    
    //////////////////////////////////////////////////////////
    
    int main()
    {
        A a( "yyy" );
        int va = a.getV();
    
        C c;
        int vc = c.getA( "xxx" ).getV();
    }
    


  • lemon03 schrieb:

    this und/oder -> statt den Punkten ausschreiben?

    Wer ist tot? Statt welcher Punkte?



  • Na sowas wie

    return this;
    

    Stelle mir auf eine verhuschte Weise vor, das man damit auch anders auf Objekte zugreifen kann als object.methode() oder so. Ich brauch das zum Abgleichen, um diese Schreibweise zu verstehen.



  • Ich verstehe die Frage auch nicht. Was hättest du gerne wie umgeschrieben?



  • lemon03 schrieb:

    Na sowas wie

    return this;
    
    struct Foo
    {
    	Foo * bar() { return this; }
    	void baz() {}
    };
    
    int main()
    {
    	Foo foo;
    	foo.bar()->baz();
    }
    

    und ... weiter?



  • lemon03 schrieb:

    Stelle mir auf eine verhuschte Weise vor, das man damit auch anders auf Objekte zugreifen kann als object.methode() oder so. Ich brauch das zum Abgleichen, um diese Schreibweise zu verstehen.

    . ist der primäre "member access operator".
    Siehe http://en.cppreference.com/w/c/language/operator_member_access

    Wenn du eine Referenz r auf ein Objekt hast oder ein Objekt o selbst, dann schreibst du r.member bzw. o.member wenn du auf das Member member des Objekts zugreifen willst.

    Wenn du einen Zeiger p auf ein Objekt hast, dann musst du den erstmal dereferenzieren um an eine Referenz auf das Objekt zu kommen.
    Dereferenzieren tut man mit * , d.h. *p steht für eine Referenz auf das Objekt auf das der Zeiger p zeigt.
    Über dieser Referenz können wir uns wieder mit "." ein Member holen.
    Macht in Summe dann (*p).member .

    Und p->member ist einfach nur eine andere Schreibweise für (*p).member . (Gilt nur wenn p wie in diesem Beispiel ein Zeiger ist!)

    Und was this angeht: this ist einfach ein Keyword das für einen Zeiger auf das Objekt steht mit dem eine Memberfunktion aufgerufen wurde.



  • ps: Man kann das ganze natürlich auch umgekehrt machen. Wenn du ein Objekt o hast, dann kannst du statt o.member natürlich auch (&o)->member schreiben.



  • Aha, danke. Das ist mir schon ein wenig klarer.


Log in to reply