Warum wird die T* operator->()
wiederholt angewendet, auch wenn sie einmal geschrieben wurde? Aber ein weiterer T& operator*()
wird einmal angewendet und sollte viele Male geschrieben werden.Warum wird der `T * operator ->()` wiederholt angewendet, auch wenn er einmal geschrieben wurde?
Wie bekannt gibt es Execute-Around Pointer Idiom in C++. More C++ Idioms/Execute-Around Pointer
Stellen Sie ein Smart-Pointer-Objekt bereit, das Aktionen vor und nach jedem Funktionsaufruf für ein Objekt transparent ausführt, da die ausgeführten Aktionen für alle Funktionen identisch sind. Und vor und nach jeder Behandlung zur Mitgliedsvariablen einer Klasse. Zum Beispiel können wir durch:
- Sperren-Mutex
- log Aktion
- visualisieren Ändern von Daten
Ich habe einige in main()
-this example:
#include <iostream>
#include <vector>
class VisualizableVector {
public:
class proxy {
public:
proxy (std::vector<int> *v) : vect (v) {
std::cout << "Before size is: " << vect->size() << std::endl;
}
std::vector<int> * operator ->() { return vect; }
std::vector<int> & operator *() { return *vect; }
~proxy() { std::cout << "After size is: " << vect->size() << std::endl; }
private:
std::vector <int> * vect;
};
VisualizableVector (std::vector<int> *v) : vect(v) {}
~VisualizableVector() { delete vect; }
proxy operator ->() { return proxy (vect); }
proxy operator *() { return proxy (vect); }
private:
std::vector <int> * vect;
};
int main()
{
VisualizableVector vecc (new std::vector<int>);
vecc->push_back (10); // 1. Note use of -> operator instead of . operator
vecc->push_back (20); // 2. ok
(*vecc)->push_back (30); // 3. ok
// (*vecc).push_back (40); // 4. error
(**vecc).push_back (50); // 5. ok
// vecc->->push_back (60); // 6. error
}
Online-Compiler Ergebnis: http://ideone.com/cXGdxW
Warum müssen wir zweimal schreiben **
, aber nur einmal ->
?
Die Betreiber geben die gleiche Sache proxy
:
proxy operator ->() { return proxy (vect); }
proxy operator *() { return proxy (vect); }
Aber warum brauchen wir *
wieder verwenden, aber wir sollten ->
nicht wieder verwenden ?:
vecc->push_back (20); // 2. ok (vecc->) is proxy
(**vecc).push_back (50); // 5. ok (*vecc) is proxy
Warum vecc->->push_back (20);
nicht?
Gibt es irgendetwas darüber in der Norm C++ (03/11/14)?
UPDATE:
In verschiedenen Fällen sollten wir 1,2 oder 3 operator->
s verwenden: http://ideone.com/89kfYF
#include <iostream>
#include <vector>
class VisualizableVector {
public:
class proxy {
public:
proxy (std::vector<int> *v) : vect (v) {
std::cout << "Before size is: " << vect->size() << std::endl;
}
std::vector<int> * operator ->() { return vect; }
std::vector<int> & operator *() { return *vect; }
~proxy() { std::cout << "After size is: " << vect->size() << std::endl; }
private:
std::vector <int> * vect;
};
VisualizableVector (std::vector<int> *v) : vect(v) {}
~VisualizableVector() { delete vect; }
proxy operator ->() { return proxy (vect); }
proxy operator *() { return proxy (vect); }
private:
std::vector <int> * vect;
};
int main()
{
VisualizableVector vecc (new std::vector<int>);
vecc->push_back(30); // ok // one ->
//vecc.operator->().push_back(30);// error // one ->
//vecc->->push_back(30); // error // two ->
vecc.operator->()->push_back(30); // ok // two ->
auto proxy3 = vecc.operator->(); // 1st operator->()
auto pointer = proxy3.operator->(); // 2nd operator->()
pointer->push_back(30); // 3rd operator->()
return 0;
}
Seite 327: Working Draft, Standard for Programming Language C++ 2014-11-19
13.5.6 Klasse Mitglied Zugang [over.ref] 1 operator-> soll eine nicht statische Memberfunktion sein, die keine Parameter annimmt. Es implementiert die Klassenmemberzugriffssyntax, die -> verwendet. postfix-expression -> templateopt id-ausdruck postfix-ausdruck -> pseudo-destruktorname Ein Ausdruck x-> m wird interpretiert als (x.operator ->()) -> m für eine Klasse Objekt x des Typs T wenn T :: operator ->() existiert und wenn der Operator als die beste Übereinstimmungsfunktion durch die Überladungsauflösung (13.3) ausgewählt ist.
I.e. x->m
ist (x.operator->())->m
.
Die kurze Antwort lautet: Weil C++ so funktioniert und Sie Ihre Klassen so geschrieben haben. –
Seitennotiz: Dies ist eine schlechte Frage, wegen der unnötigen Verwendung von "neu" (ohne Pairing zu "löschen") –
IMHO, 'operator->' und 'operator *' Rückgabe genau der gleichen Art, ist schlecht an sich. –