2009-02-06 5 views
67

Es wäre sehr nützlich, die. Operator in C++ und gibt einen Verweis auf ein Objekt zurück.Warum können Sie das '.' Operator in C++?

können Sie operator-> überlasten und operator* aber nicht operator.

Gibt es einen technischen Grund dafür?

+4

Können Sie ein Beispiel geben, wenn Sie das '.' Operator? –

+4

Im Allgemeinen ist der Anwendungsfall "intelligente Referenzen". Eine Art Proxy. – ddaa

+2

@Gamecat: Lesen Sie durch [diese] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1671.pdf) Vorschlag, um die Fähigkeit hinzuzufügen, "Operator" und 'operator. *', es hat ein paar Beispiele. – Mankarse

Antwort

51

Siehe this quote from Bjarne Stroustrup:

Operator. (Punkt) könnte prinzipiell mit der gleichen Technik wie für -> überladen werden. Dies kann jedoch zu Fragen darüber führen, ob eine Operation für die Objektüberladung gedacht ist. oder ein Objekt, auf das Bezug genommen wird. Zum Beispiel:

class Y { 
public: 
    void f(); 
    // ... 
}; 

class X { // assume that you can overload . 
    Y* p; 
    Y& operator.() { return *p; } 
    void f(); 
    // ... 
}; 

void g(X& x) 
{ 
    x.f(); // X::f or Y::f or error? 
} 

Dieses Problem kann auf verschiedene Arten gelöst werden. Zur Zeit der Standardisierung war es nicht offensichtlich, welcher Weg am besten wäre. Weitere Informationen finden Sie unter Details The Design and Evolution of C++.

+0

Vollständiges Zitat von TDaEoC++ in meiner Antwort. – ddaa

+12

Ich bin versucht, dies für Plagiat/Neufärbung zu stimmen. Zitiere, zitiere wortwörtlich, nicht zwicken. Und verwende die Angebotsformate. –

+0

sehr gutes Beispiel und Erklärung. – Manju

27

Stroustrup has an answer for this question:

Operator. (Punkt) könnte prinzipiell mit der gleichen Technik überladen werden wie für -> verwendet. Dies kann jedoch zu Fragen führen, ob eine Operation für das Objekt Überladung gemeint ist. oder ein Objekt, bezogen auf von. Zum Beispiel:

class Y { 
public: 
    void f(); 
    // ... 
}; 
class X { // assume that you can overload . 
    Y* p; 
    Y& operator.() { return *p; } 
    void f(); 
    // ... 
}; 
void g(X& x) 
{ 
    x.f(); // X::f or Y::f or error? 
} 

Dieses Problem kann in mehrere Weise gelöst werden. Zum Zeitpunkt der Standardisierung, war es nicht offensichtlich, welcher Weg wäre am besten. Weitere Informationen finden Sie unter D&E.

+0

Siehe meinen Kommentar zu Antons Antwort – slashmais

47

Stroustrup sagte, dass C++ eine erweiterbare, aber nicht änderbare Sprache sein sollte.

Der Operator dot (attribute access) wurde als zu nah am Kern der Sprache angesehen, um eine Überladung zu ermöglichen.

Siehe The Design and Evolution of C++, Seite 242, Abschnitt 11.5.2 Smart References.

Wenn ich eine Überlastung der Bediener zu ermöglichen, entschied ->, ich natürlich geprüft, ob Betreiber . könnte in ähnlicher Weise überlastet werden.

Zu diesem Zeitpunkt betrachtete ich die folgenden Argumente als schlüssig: Wenn obj ein Klassenobjekt ist, hat obj.m eine Bedeutung für jedes Mitglied m der Klasse dieses Objekts. Wir versuchen, die Sprache nicht veränderbar zu machen, indem wir eingebaute Operationen neu definieren (obwohl diese Regel für = aus unerfindlichen Gründen und für unäre & verletzt wird).

Wenn wir das Überladen von . für eine Klasse X zulassen, können wir auf Elemente von X nicht normal zugreifen. wir müssten einen Zeiger und -> verwenden, aber -> und & könnten auch neu definiert worden sein. Ich wollte eine erweiterbare Sprache, keine veränderbare.

Diese Argumente sind schwerwiegend, aber nicht schlüssig. Insbesondere schlug Jim Adcock 1990 vor, die Überlastung des Betreibers .genau dem Betreiber -> zu erlauben.

Das "I" in diesem Zitat ist Bjarne Stroustrup. Sie können nicht autoritärer sein als das.

Wenn Sie C++ wirklich verstehen wollen (wie in "warum ist es so"), sollten Sie unbedingt dieses Buch lesen.

1

Es ist sehr einfach zu verstehen, wenn Sie durch den internen Mechanismus des Aufrufs der Operatorfunktion, gehen Sprich ein Klassenkomplex kann zwei Mitglieder r für Realteil und ich für Imaginärteil haben. Say Komplex C1 (10,20), C2 (10,2) // Wir nehmen an, dass es innerhalb der Klasse bereits einen Konstruktor mit zwei Argumenten gibt. Wenn Sie nun C1 + C2 als Anweisung schreiben, dann versuchen Sie, die überladene Version des Operators + für die komplexe Zahl zu finden. Jetzt gehen wir davon aus, dass ich überladen + Operator, also C1 + C2 intern übersetzt als c1.operator + (c2) Jetzt nehmen für die Zeit Wesen, die Sie überladen können "." Operator. so denken jetzt Aufruf folgende C1.disp() // Anzeigeinhalt eines komplexen Objekts nun als interne Darstellung C1.operator. (------), völlig chaotisch Dinge geschaffen darzustellen versuchen. Das ist der Grund, warum wir nicht "überladen" können. Operator

+1

Einige Leute sagen, dass interne Übersetzung nicht überladenen "Operator" rufen sollte – curiousguy