52 Stimmen

C++: Bequemer Weg zum Zugriff auf operator[] aus der Klasse heraus?

Ich habe eine C++-Klasse, die Überladungen operator[] der Operator für tiefgestellte Arrays und Klammern. Dies ist sehr praktisch außerhalb meiner Klasse, wo ich schreiben kann foo[bar ]. Ich kann jedoch nicht herausfinden, wie ich diese Notation verwenden kann, wenn ich Methoden implementiere innerhalb meine Klasse.

Ich weiß, dass ich schreiben kann operator[](bar) o this->operator[](bar) aber diese sind ziemlich unhandlich und nehmen dem Betreiber viel von seinem Komfort. (Ich weiß auch, ich kann einfach eine neue Methode hinzufügen, die den Operator aufruft.) Gibt es eine Möglichkeit, ich kann schreiben this[bar] o this->[bar] oder etwas ähnlich Schönes?

77voto

Evan Teran Punkte 83711
(*this)[bar];

funktioniert bei mir einwandfrei.

0 Stimmen

@TanishqBanyal Die Antwort lautet meist "weil es nicht funktioniert" :-). Genauer gesagt liegt es daran, dass der Rückgabetyp von operator-> ist ein POINTER. Sie könnten dies tun ... this->operator[](bar] aber das ist abscheulich. (Beispiel: godbolt.org/z/n4K7W9Yd3 )

8voto

Mr Fooz Punkte 102791

Verwenden Sie

(*this)[bar]

zum Aufruf der operator[] des Instanzobjekts.

Angenommen, bar ist eine ganze Zahl (oder kann automatisch in eine umgewandelt werden), this[bar] behandelt die this Zeiger als ein Array und indiziert die bar -te Element dieses Arrays. Es sei denn, this in einem Array ist, führt dies zu einem undefinierten Verhalten. Wenn bar nicht ganzzahlig ist, erwarten Sie einen Kompilierfehler.

0 Stimmen

Eine Überlastung der operator[] kann auch andere Dinge als ganzzahlige Typen als Argumente akzeptieren, so dass es möglicherweise überhaupt nicht kompiliert werden kann, geschweige denn in den bar -Element dieses "Arrays".

1 Stimmen

@user904963 gute Punkte. Ich habe den letzten Absatz aktualisiert.

4voto

Robert Gould Punkte 66858

Ich verwende eine at()-Funktion und lasse den operator[] die at()-Funktion hinter den Kulissen aufrufen, so dass operator[] nur syntaktischer Zucker ist. Das ist, wie std::vector tut es, so scheint es wie eine vernünftige (mit Vorrang) Weg, es zu tun.

Nun zu einem kompletten syntaktischen Zucker-Hack (ich kann ihn nicht uneingeschränkt empfehlen, aber vielleicht gefällt er Ihnen):

class Widget
{
    Widget&     self;
public:
    Widget() :self(*this)
    {}

    void operator[](int)
    {
        printf("hello");
    }

    void test()
    {
        //scripting like sugar
        //you pay the price of an extra reference per class though
        self[1]; 
    }
};

int main(int argc, char* argv[])
{
    Widget w;
    w[1];
    w.test();
    return 0;
}

Auch wenn Sie dies kostenlos tun wollen, ohne die Kosten für die Referenz zu bezahlen, UND ein Anhänger einer bösen Sekte sind, die Programmierer leiden lässt, könnten Sie das tun:

#define self (*this)

Ich glaube, so sind die meisten Handles in Apples NS-API implementiert...

0 Stimmen

Das gefällt mir in gewisser Weise, denn in den letzten Minuten habe ich self = *this gesetzt und dann self verwendet. Danke!

8 Stimmen

Bei Vector ist es umgekehrt, weil vector::at() vor dem Aufruf von operator[]() eine Bereichsprüfung durchführen muss.

2 Stimmen

Ein Wort der Vorsicht mit dem Widget& self Version: Wenn Sie Ihre Klasse trotzdem kopieren wollen, verwenden Sie operator= usw., müssen Sie eine Menge zusätzlicher neuer Formulare schreiben.

3voto

Michael Kristofik Punkte 32950

Eine Alternative zu (*this)[bar] ist die Verwendung einer benannten Mitgliedsfunktion, die die Arbeit von operator[] . Überladene Operatoren machen es Ihren Benutzern leichter. Noch wichtiger ist, dass sie Teil der Klasse sind. Schnittstelle . Fragen Sie sich, ob es wirklich sinnvoll ist, Ihre Klasse im Sinne ihrer eigenen öffentlichen Schnittstelle zu implementieren. Wenn nicht, schlage ich vor, eine separate (geschützte oder private) Mitgliedsfunktion zu schreiben, die die Arbeit erledigt, und dann operator[] und alle anderen Funktionen rufen sie auf.

2voto

user3199814 Punkte 21
 operator[](bar) 

Das sollte auch funktionieren. Bei mir funktioniert es!

0 Stimmen

In meiner Frage ist das die erste Option, die ich erwähne.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X