Frage

Diese Frage hat hier bereits eine Antwort:

Mein Problem ist einfach. Ich habe eine Klassenvorlage, die einen Zeiger auf einen dynamisch zugewiesenen Typ hält. Ich möchte den Indirektionoperator so überladen, dass ich mich mit dem -> Operator auf die Klassenvorlageinstanz beziehe.

template<class T>
class MyClass
 {
  T *ptr;
  ...
  // created dynamic resource for ptr in the constructor
 };

Erstellen Sie eine Myclass von irgendeiner Art:

MyClass<SomeObject> instance;

Also, was ich will, ist, anstatt tippen zu müssen:

instance.ptr->someMemberMethod();

Ich tippe einfach:

intance->someMemberMethod();

Obwohl instance Ist kein Zeiger, es verhält sich so, als wäre es der Zeiger instance enthält. Wie schlägt ich diese Lücke, indem Sie den Bediener überladen?

War es hilfreich?

Lösung

Sie können nur überlasten operator-> und operator*:

template<class T>
class MyClass
{
    T* ptr;

public:
    T* operator->() {
        return ptr;
    }

    // const version, returns a pointer-to-const instead of just a pointer to
    // enforce the idea of the logical constness of this object 
    const T* operator->() const {
        return ptr;
    }

    T& operator*() {
        return *ptr;
    }

    // const version, returns a const reference instead of just a reference
    // to enforce the idea of the logical constness of this object
    const T& operator*() const {
        return *ptr;
    }
};

Beachten Sie, dass Sie aufgrund einer Entwurfsentscheidung durch den Schöpfer der Sprache das nicht überladen können . Operator.

Sie könnten das auch denken operator* würde das überladen Multiplikation Operator anstelle des Dereferenzoperators. Dies ist jedoch nicht der Fall, da der Multiplikationsoperator ein einziges Argument einnimmt (während der Dereferenzoperator keine Argumente nimmt), und aus diesem Grund kann der Compiler erkennen, welches ist.

Beachten Sie schließlich das operator-> Gibt einen Zeiger aber zurück operator* Gibt eine Referenz zurück. Es ist leicht, sie versehentlich zu verwirren.

Andere Tipps

Überladen die -> Operator:

template <typename T> class MyClass
{
    T * p;
public:
    T       * operator->()       { return p; }  // #1
    T const * operator->() const { return p; }
};

Beachten Sie, dass beide Überladungen mutieren das Objekt nicht; Trotzdem entscheiden wir uns, die Nummer 1 nicht zu kontrollieren, damit wir den Punkt auf den Punkte nachlassen. Dies wird manchmal als "Deep Constness Propagation" oder so bezeichnet. Die Sprache D geht so viel weiter.

Der Mitglied des Mitgliedszugriffs kann überladen werden, um einen Zeiger an das zugegriffene Objekt zurückzugeben:

T * operator->() {return ptr;}
T const * operator->() const {return ptr;}

Möglicherweise möchten Sie auch den Ehrerbieterbetreiber, damit er sich noch mehr wie ein Zeiger anfühlt. Dies gibt stattdessen eine Referenz zurück:

T & operator*() {return *ptr;}
T const & operator*() const {return *ptr;}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top