Anwendungsbeispiel für this ???



  • Vieleicht liegt es an meiner Unkenntnis. Vieleicht an meiner Art zu programmieren.
    Ich übergebe Objekte meistens über ein Drittes oder Beide wurden im selben lokalen Bereich erstellt.
    Ich kam wirklich erst einmal in die Versuchung den this->Zeiger einzusetzen. Da kann doch was nicht stimmen 😃 Die meisten src's die ich sehe sind aber voll mit this->Zeigern.

    Wann ist er sinnvoll oder unabdingbar?



  • this-> in der Form benutze ich eigentlich nie, aber this oder *this schon eher(Als Übergabeparameter von irgendwelchen Funktionen). Auch häufig im Bezug auf boost.bind.



  • belsina schrieb:

    Wann ist er sinnvoll oder unabdingbar?

    Es gibt einfach Situationen in denen man einen Zeiger auf's "eigene" Objekt *braucht*. Einfaches Beispiel (Listener Pattern):

    class EventSink // der wo events empfangen/verarbeiten will (abstrakt)
    {
        virtual void EventFoo() = 0;
        virtual void EventBar() = 0;
    };
    
    class EventSource // der wo events ausspuckt
    {
    public:
        void AttachSink(EventSink* sink);
        void DetachSink(EventSink* sink);
    };
    
    class HinzKunz : public EventSink
    {
    public:
        explicit HinzKunz()
        {
            m_eventSource.reset(new EventSource()); // angenommen die m_eventSource brauchen wir aus irgendeinem Grund hier als member
            m_eventSource->AttachSink(this); // so, und nu mach dashier mal ohne "this" keyword :)
        }
    
        ~HinzKunz()
        {
            m_eventSource->DetachSink(this);
        }
    
        virtual void EventFoo()
        {
            std::cout << "HinzKunz bekommt FOO!\n";
        }
    
        virtual void EventBar()
        {
            std::cout << "HinzKunz bekommt BAR!\n";
        }
    
    private:
        std::auot_ptr<EventSource> m_eventSource;
    };
    

    Was JustAnotherNoob angesprochen hat (boost::bind) ist im Prinzip ähnlich: da braucht man eben auch "this" um einer fremden Klasse (in dem Fall dem von boost::bind erzeugten Funktor) den Zeiger auf das "eigene" Objekt mitzugeben, damit dieses Objekt dann "zurückrufen" kann, also irgendwelche Funktionen auf dem "eigenen" Objekt ausführen.

    Ein anderes Beispiel wo man ohne "this" nicht weit kommt wäre das CRTP: http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

    ----

    Was man dagegen oft sieht, nämlich statt "m_myMember = 123;" eben "this->m_myMember = 123;" zu schreiben halte ich persönlich nicht für sinnvoll oder gut. Um Member-Variablen von anderen Variablen (lokal, Parameter etc.) zu unterscheiden verwende ich (und viele viele andere) hier den Prefix "m_". Das hat IMO mehrere Vorteile.



  • Der einfachste Fall dürfte der Assignment-Operator einer Klasse sein:

    class A
    {
    public:
       ...
       A & operator = (A const & rhs)
       {
          if (this != &rhs)
          {
             ...
          }
          return *this;
       }
       ...
    }
    


  • class Bar
    {
        int a;
         void foo(int a)
         {
             this->a = a; // temp. a in das member-a zuweisen
         }
    };
    

    Ohne this würde das nicht gehen.



  • Bulli schrieb:

    class Bar
    {
        int a;
         void foo(int a)
         {
             this->a = a; // temp. a in das member-a zuweisen
         }
    };
    

    Ohne this würde das nicht gehen.

    Doch :p

    class Bar
    {
        int a;
         void foo(int a)
         {
             Bar::a = a; // temp. a in das member-a zuweisen
         }
    };
    


  • Wenn schon denn schon:

    class Bar
    {
    public:
        int a;
         void foo(int a)
         {
            ((Bar*)(*((&a)-1)))->a = a;
         }
    };
    


  • jencas schrieb:

    Der einfachste Fall dürfte der Assignment-Operator einer Klasse sein:

    class A
    {
    public:
       ...
       A & operator = (A const & rhs)
       {
          if (this != &rhs)
          {
             ...
          }
          return *this;
       }
       ...
    }
    

    Nur ist es nicht üblich, den Assignment-Operator so zu implementieren. Viel eher über Copy&Swap...



  • Nexus schrieb:

    Nur ist es nicht üblich, den Assignment-Operator so zu implementieren. Viel eher über Copy&Swap...

    Diese Methode hat schon auch seinen Verwendungszweck. Vor allem, wenn die Objekte relativ gross sind, dann kann es durchaus Sinn machen es durch dieses Vorgehen zu implementieren.
    Aber es ist schon sicherer mit Copy&Swap, da man da nicht viel falsch machen kann. (auf jeden Fall nicht im Assignment-Operator.. :))



  • Ohne this würde das nicht gehen.

    Und mit this wirds verwirrend.
    vor allem toll finde ich in der Hinsicht auch folgendes Konstrukt.

    class A
    	{
    	public:
    		A(int a) :
    			a(a)
    			{}
    	private:
    		int a;
    	};
    


  • JustAnotherNoob schrieb:

    vor allem toll finde ich in der Hinsicht auch folgendes Konstrukt.

    Dann würdest du meine Sourcen hassen.

    Ich bennene Übergabeparameter nicht selten identisch wie Membervariablen. Warum? Erstens hasse ich kryptische Kürzel um Membervariablen sichtbar zu machen (dann finde ich das selbst ein "this->" besser lesbarer ist, und vor allem wirklich beschreibt um was es geht. Zweitens benenne ich variablen nach dem was sie machen mit einheitlicher pascalCase-Notation.

    Wobei ich zugebe das ich mit deiner Einrückungsform auch Leseprobleme habe.

    cu André


Log in to reply