2017-01-22 2 views
-2

Wenn ich einen Std :: Vector habe, kann ich auf ein Mitglied zugreifen, weil der eckige Klammeroperator in der Vektorklasse überladen ist. Wenn ich einen Zeiger auf einen Vektor habe, kann ich den Zeiger dereferenzieren und diesen Operator verwenden. Aber mit dem Pfeil -> Operator wird es mich nicht benutzen lassen. Beispiel:Warum funktionieren [] Klammern nicht, wenn ein Zeiger dereferenziert wird?

std::vector<int> myVector;  
std::vector<int>* pToVector; 
myVector[4] = 0;     // Works fine 
(*pToVector)[4] = 0;    // Works fine 
pToVector->[4] = 0;    // Doesn't work 
(pToVector->)[4] = 0;    // Doesn't work 

sehen, als ob die -> Pfeil Bediener den Zeiger dereferenziert, gibt es einen Grund, nicht zu erwarten, dass dies funktionieren würde? Oder ist es nur eines dieser Dinge über die Sprache?

Danke.

+1

Die ersten beiden Zuweisungen funktionieren möglicherweise, aber Sie greifen außerhalb der Containergrenzen zu, dh UB.Sie müssen es wie folgt deklarieren: 'std :: vector myVector (5)', das den notwendigen Platz für den Zugriff auf 'myVector [4] zuweist. Die letzten beiden sind ungültige Konstrukte – doug

+0

Es ist eine falsche Syntax. Der Pfeiloperator gibt Ihnen * objec. Struktur so pToVector -> [4] = 0 ähnlich wie * pToVector. [4] = 0. Weder diese Zeile (pToVector ->) [4] noch dieser pToVector -> [4] wird nicht funktionieren – arturx64

+0

Warum erwarten Sie, dass es funktioniert? "a-> b" bedeutet "(* a) .b". Also kann "a -> [b]' "(* a). [] Bedeuten, was keinen Sinn ergibt. – HolyBlackCat

Antwort

1

Die korrekte Syntax für die zweiten zwei Zeilen wäre:

(*pToVector)[4] = 0; 
//dereference the pointer and then call operator[] on the object returned by the dereference 

Sie den -> Operator wie diese regelmäßige Mitgliederfunktionen zuzugreifen verwenden:

pToVector->size(); 

Technisch Sie könnten versuchen, yo das nennen operator[] mit Namen, aber es ist ausführlicher.

3
std::vector<int> myVector;  
std::vector<int>* pToVector; 
myVector[4] = 0;     // Works fine. 
(*pToVector)[4] = 0;    // Works fine 
pToVector->[4] = 0;    // Doesn't work 
(pToVector->)[4] = 0;    // Doesn't work 

Wenn Sie einen Zeiger auf ein Objekt verwenden, muss einen überladenen Operator der Klasse des Objekts zuzugreifen, werden Sie es explizit nennen.

pToVector->operator[](4) 

... By the way, einen Index außerhalb myVector.size() Zugriff ist nicht definiertes Verhalten. Dazu gehören die Anweisungen mit der Kommentaranmerkung in Ihrem Code über // Works fine.

0

Der Operator -> ist nicht nur dereferenziert, es greift auch auf ein Mitglied zu. Sie greifen auf ein Element *, kein Mitglied. -> hätte definiert werden können, um dies zu ermöglichen, war es aber nicht.

* Um genauer zu sein, wird ein Vektor so dass Sie auf ein Objekt zugreifen, als ob es sich um ein Element eines Arrays waren, aber nicht die Syntax ändern.

+0

"Element" gegen "Mitglied"? C++ hat keinen solchen Unterschied; Die Begriffe werden synonym verwendet. – MSalters

+0

@MSalters Haben Sie Beispiele, wo der C++ - Standard auf Klassenelemente oder auf Array-Member verweist? Ich finde sie nicht, aber es ist möglich, dass ich etwas übersehen habe. – hvd

+0

@hvd: Ich wurde ein wenig in die Irre geführt, indem ich Ihre Aussage las, als "' -> 'auf ein Element zugreift", aber macht nichts. C++ definiert formal _element_ nicht und der Standard hat nur "element_type" im Index, aber 1,8/2 lässt ziemlich wenig Zweifel aufkommen. Das heißt, in dieser Frage greift '[]' nicht auf ein Array-Element zu, sondern bezieht sich auf die Member-Funktion 'operator []'. Gleiche Token, unterschiedliche Bedeutung. – MSalters

0

-> Operator ist Ersatz für Punktoperator, außer dass es einen Zeiger zuerst dereferenziert. Es wird verwendet, um auf Attribute (Mitglieder und Funktionen) zuzugreifen. Für Ihre Operation ist operator[] das Attribut. So wird pToVector->operator[](4) auf (*pToVector)[4] = 0

+0

'->' ist nicht auf Datenmitglieder beschränkt, es funktioniert auch mit Member-Funktionen. Und offensichtlich ist operator [] 'ein Funktionsmember, keine Daten. – MSalters

+0

'attribute' Wort ist besser geeignet. Aber ich könnte sowohl Mitglieder als auch Methoden meinen, während ich das Datenfeld @MSalters – snr

+0

sage "Attribut" ist kein Schlüsselwort, und [Attribute] (http://en.cppreference.com/w/cpp/language/attributes) sind etwas völlig anderes . Auch "Mitglieder und Methoden" machen wenig Sinn; Methoden sind eine Teilmenge von Mitgliedern. (nämlich Mitgliedsfunktionen). – MSalters

0

angewendet. Der Grund ist, dass ein Operator ist, und die kurze Operator-Syntax erfordert keine Zugriffsoperatoren für Mitglieder. Dies gilt für die beiden Zugriffsoperatoren . und ->, was sinnvoll ist, weil letzteres nur eine Kurzschrift für (*a).b ist.

z. alle nicht anerkannten a. & b, a->^b

Technisch es gilt auch für die selteneren .* und ->*. Beachten Sie, dass letzteres ist nicht-> gefolgt von operator*, aber ein Zeiger auf Mitglied Zeigerdereferenz.

Verwandte Themen