Wann sollte ich den `this`-Zeiger explizit verwenden?

Lesezeit: 2 Minuten

Wann soll ich explizit schreiben this->member in einer Methode einer Klasse?

  • Ich bin mir sicher, dass dies ein Dupe ist, aber es ist natürlich nicht durchsuchbar. Nicht zum ersten Mal wünschte ich, dieser Zeiger würde self heißen!

    anon

    14. Juni 2009 um 18:11 Uhr

  • Nicht nur das, ich wünschte, es wäre eine Referenz.

    – rlbond

    14. Juni 2009 um 18:25 Uhr

  • Dasselbe. 😐 Hier übrigens der Grund: research.att.com/~bs/bs_faq2.html#this

    – GManNickG

    14. Juni 2009 um 18:26 Uhr

  • Diese Methode funktioniert offensichtlich nicht, wenn die Person die Antwort nicht kennt.

    – Fragen

    15. Juni 2009 um 16:10 Uhr

  • @JohnH.: Hm, sieht aus wie research.att.com/~bs/ ist jetzt stroustrup.com. Neuer Link: stroustrup.com/bs_faq2.html#this

    – GManNickG

    17. Juli 2016 um 19:29 Uhr

Wann sollte ich den this Zeiger explizit verwenden
Fragen

Normalerweise müssen Sie nicht, this-> ist impliziert.

Manchmal gibt es eine Namensmehrdeutigkeit, die verwendet werden kann, um Klassenmitglieder und lokale Variablen zu disambiguieren. Hier ist jedoch ein ganz anderer Fall, wo this-> ist ausdrücklich erforderlich.

Betrachten Sie den folgenden Code:

template<class T>
struct A {
   int i;
};

template<class T>
struct B : A<T> {

    int foo() {
        return this->i;
    }

};

int main() {
    B<int> b;
    b.foo();
}

Wenn Sie weglassen this->weiß der Compiler nicht zu behandeln ida es in allen Instanziierungen von vorhanden sein kann oder nicht A. Um ihm das zu sagen i ist tatsächlich Mitglied A<T>für alle Tder this-> Präfix ist erforderlich.

Hinweis: Es ist möglich, noch wegzulassen this-> Präfix durch Verwendung von:

template<class T>
struct B : A<T> {

    using A<T>::i; // explicitly refer to a variable in the base class

    int foo() {
        return i; // i is now known to exist
    }

};

  • Nette Verwendung der Verwendungsdeklaration 🙂

    – Faisal Vali

    14. Juni 2009 um 18:42 Uhr

  • Dies ist ein besonders unangenehmer Fall. Ich bin schon mal davon gebissen worden.

    – Jason Baker

    14. Juni 2009 um 19:53 Uhr

  • Das ist vielleicht eine dumme Frage, aber ich verstehe nicht warum i möglicherweise nicht vorhanden in A. Könnte ich ein Beispiel bekommen?

    – Cam Jackson

    19. Dezember 2013 um 1:08 Uhr

  • @CamJackson Ich habe den Code in Visual Studio ausprobiert. Die Ergebnisse sind gleich, egal ob “this->” existiert oder nicht. Irgendeine Idee?

    – Peng Zhang

    12. Januar 2014 um 10:57 Uhr

  • @CamJackson: Man kann Klassen auf Typ spezialisieren: template<> struct A<float> { float x; };

    – Macke

    3. Dezember 2014 um 7:33 Uhr

1646988608 845 Wann sollte ich den this Zeiger explizit verwenden
PaV

Wenn Sie eine lokale Variable in einer Methode mit demselben Namen wie ein vorhandenes Mitglied deklarieren, müssen Sie this->var verwenden, um auf das Klassenmitglied statt auf die lokale Variable zuzugreifen.

#include <iostream>
using namespace std;
class A
{
    public:
        int a;

        void f() {
            a = 4;
            int a = 5;
            cout << a << endl;
            cout << this->a << endl;
        }
};

int main()
{
    A a;
    a.f();
}

Drucke:

5
4

  • Ich würde besser cout << A::a << endl; stattdessen. ``this" ist in diesem Fall unwichtig.

    – siddhant3s

    15. Juni 2009 um 0:15 Uhr

  • Ich würde lieber nur den Namenskonflikt mit Konventionen wie “m_a” oder “a_” vermeiden.

    – Tom

    15. Juni 2009 um 5:28 Uhr

Es gibt mehrere Gründe, warum Sie möglicherweise verwenden müssen this Zeiger explizit.

  • Wenn Sie eine Referenz auf Ihr Objekt an eine Funktion übergeben möchten.
  • Wenn ein lokal deklariertes Objekt mit demselben Namen wie das Mitgliedsobjekt vorhanden ist.
  • Wenn Sie versuchen, auf Mitglieder von zuzugreifen abhängige Basisklassen.
  • Einige Leute bevorzugen die Notation, um Member-Zugriffe in ihrem Code visuell zu disambiguieren.

Obwohl ich es normalerweise nicht besonders mag, habe ich gesehen, dass andere dies verwenden -> einfach um Hilfe von Intellisense zu erhalten!

Wann sollte ich den this Zeiger explizit verwenden
John Dibling

Es gibt nur wenige Fälle, in denen verwendet wird this Muss verwendet werden, und es gibt andere, bei denen die verwendet werden this Zeiger ist eine Möglichkeit, ein Problem zu lösen.

1) Alternativen verfügbar: Zum Auflösen von Mehrdeutigkeiten zwischen lokalen Variablen und Klassenmitgliedern, wie durch @ASk veranschaulicht.

2) Keine Alternative: Um einen Zeiger oder eine Referenz auf zurückzugeben this aus einer Mitgliedsfunktion. Dies wird häufig beim Überladen gemacht (und sollte gemacht werden). operator+, operator-, operator=etc:

class Foo
{
  Foo& operator=(const Foo& rhs)
  {
    return * this;
  }
};

Dies ermöglicht eine Redewendung, die als “Methodenverkettung“, wo Sie mehrere Operationen an einem Objekt in einer Codezeile ausführen. Wie zum Beispiel:

Student st;
st.SetAge (21).SetGender (male).SetClass ("C++ 101");

Manche halten das für prägnant, andere für ein Gräuel. Zählen Sie mich zur letzteren Gruppe.

3) Keine Alternative: So lösen Sie Namen in abhängigen Typen auf. Dies tritt auf, wenn Vorlagen verwendet werden, wie in diesem Beispiel:

#include <iostream>


template <typename Val>
class ValHolder
{
private:
  Val mVal;
public:
  ValHolder (const Val& val)
  :
    mVal (val)
  {
  }
  Val& GetVal() { return mVal; }
};

template <typename Val>
class ValProcessor
:
  public ValHolder <Val>
{
public:
  ValProcessor (const Val& val)
  :
    ValHolder <Val> (val)
  {
  }

  Val ComputeValue()
  {
//    int ret = 2 * GetVal();  // ERROR:  No member 'GetVal'
    int ret = 4 * this->GetVal();  // OK -- this tells compiler to examine dependant type (ValHolder)
    return ret;
  }
};

int main()
{
  ValProcessor <int> proc (42);
  const int val = proc.ComputeValue();
  std::cout << val << "\n";
}

4) Verfügbare Alternativen: Als Teil des Codierungsstils, um zu dokumentieren, welche Variablen Mitgliedsvariablen im Gegensatz zu lokalen Variablen sind. Ich bevorzuge ein anderes Namensschema, bei dem Member-Variablen niemals denselben Namen wie Locals haben können. Derzeit verwende ich mName für Mitglieder u name für Einheimische.

  • Für Punkt 3, wenn Sie “keine Alternative” sagen, gibt es tatsächlich ein paar andere Möglichkeiten: 1) int ret = 6 * VahHolder<Val>::GetVal(); oder 2) in der Klasse (funktioniert nicht) using ValHolder<Val>::GetVal; macht auch die uneingeschränkte Suche für GetVal möglich, sogar in einem abhängigen Kontext. godbolt.org/z/n5PY3j51c

    – Chris Uzdavinis

    25. Februar um 13:47 Uhr

1646988610 83 Wann sollte ich den this Zeiger explizit verwenden
Zebrabox

  1. Wo eine Mitgliedsvariable durch eine lokale Variable ausgeblendet würde
  2. Wenn Sie nur ausdrücklich klarstellen möchten, dass Sie eine Instanzmethode / -variable aufrufen

Einige Codierungsstandards verwenden Ansatz (2), da sie behaupten, dass dies den Code leichter lesbar macht.

Beispiel:

Angenommen, MyClass hat eine Member-Variable namens “count”.

void MyClass::DoSomeStuff(void)
{
   int count = 0;

   .....
   count++;
   this->count = count;
}

  • Für Punkt 3, wenn Sie “keine Alternative” sagen, gibt es tatsächlich ein paar andere Möglichkeiten: 1) int ret = 6 * VahHolder<Val>::GetVal(); oder 2) in der Klasse (funktioniert nicht) using ValHolder<Val>::GetVal; macht auch die uneingeschränkte Suche für GetVal möglich, sogar in einem abhängigen Kontext. godbolt.org/z/n5PY3j51c

    – Chris Uzdavinis

    25. Februar um 13:47 Uhr

1646988610 959 Wann sollte ich den this Zeiger explizit verwenden
rlbond

Ein weiterer Fall ist der Aufruf von Operatoren. ZB statt

bool Type::operator!=(const Type& rhs)
{
    return !operator==(rhs);
}

Sie können sagen

bool Type::operator!=(const Type& rhs)
{
    return !(*this == rhs);
}

Was vielleicht besser lesbar ist. Ein weiteres Beispiel ist das Copy-and-Swap:

Type& Type::operator=(const Type& rhs)
{
    Type temp(rhs);
    temp.swap(*this);
}

Ich weiß nicht, warum es nicht geschrieben wird swap(temp) aber das scheint üblich zu sein.

  • Beachten Sie in Ihrem letzten Fall, dass Sie einen Nicht-const Mitgliedsfunktion auf einer temporären (Type(rhs).swap(*this); ist legal und korrekt), aber ein Temporär kann nicht an einen nicht konstanten Referenzparameter gebunden werden (der Compiler lehnt ab swap(Type(rhs)); ebenso gut wie this->swap(Type(rhs));)

    – Ben Voigt

    18. März 2019 um 14:51 Uhr

990370cookie-checkWann sollte ich den `this`-Zeiger explizit verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy