2009-02-06 13 views
67

Sarebbe molto utile essere in grado di sovraccaricare il. operatore in C++ e restituisce un riferimento a un oggetto.Perché non riesci a sovraccaricare il '.' operatore in C++?

È possibile sovraccaricare operator-> e operator* ma non operator.

C'è una ragione tecnica per questo?

+4

Puoi dare un esempio di quando vuoi sovrascrivere il '.' operatore? –

+4

Generalmente, il caso d'uso è "riferimenti intelligenti". Una specie di proxy. – ddaa

+2

@Gamecat: leggi questa proposta (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1671.pdf) per aggiungere la possibilità di sovraccaricare l'operatore '' e 'operatore. *', ha alcuni esempi. – Mankarse

risposta

51

Vedi this quote from Bjarne Stroustrup:

Operator. (punto) potrebbe in teoria essere sovraccaricato usando la stessa tecnica come usato per ->. Tuttavia, fare ciò può portare alle domande sul fatto che un'operazione sia pensata per l'overloading dell'oggetto. o un oggetto cui si fa riferimento. Ad esempio:

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? 
} 

Questo problema può essere risolto in diversi modi. Al momento della standardizzazione , non era ovvio quale fosse la soluzione migliore. Per ulteriori dettagli su , vedere The Design and Evolution of C++.

+0

Completa citazione da TDaEoC++ nella mia risposta. – ddaa

+12

Sono tentato di votare per plagio/ricolorazione. Quando si cita, citare testualmente, non modificare. E usa i formati delle quote. –

+0

ottimo esempio e spiegazione. – Manju

27

Stroustrup has an answer for this question:

Operator. (punto) in linea di principio potrebbe essere sovraccaricato utilizzando la stessa tecnica di utilizzato per ->. Tuttavia, così facendo, può portare a domande se l'operazione è destinata all'overload dell'oggetto . o un oggetto riferito a da. Ad esempio:

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? 
} 

Questo problema può essere risolto in vari modi . Al momento della standardizzazione, non era ovvio quale sarebbe stato il migliore . Per ulteriori dettagli, vedere D&E.

+0

Vedere il mio commento sulla risposta di Anton – slashmais

47

Stroustrup ha detto che C++ dovrebbe essere un linguaggio estensibile, ma non modificabile.

L'operatore punto (accesso attributo) è stato visto come troppo vicino al nucleo della lingua per consentire l'overloading.

Vedere The Design and Evolution of C++, pagina 242, sezione 11.5.2 Riferimenti smart.

Quando ho deciso di permettere il sovraccarico dell'operatore ->, mi viene spontaneo considerare se operatore . potrebbe essere simile sovraccarico.

Al momento, ho considerato conclusivi i seguenti argomenti: Se obj è un oggetto di classe, allora obj.m ha un significato per ogni membro m della classe di quell'oggetto. Cerchiamo di non rendere la lingua mutabile ridefinendo le operazioni incorporate (anche se tale regola viene violata per = per un disperato bisogno e per unario &).

Se fosse consentito il sovraccarico di . per una classe X, non saremmo in grado di accedere ai membri di X in modo normale; dovremmo usare un puntatore e ->, ma -> e & potrebbero anche essere stati ridefiniti. Volevo un linguaggio estensibile, non mutabile.

Questi argomenti sono importanti, ma non determinanti. In particolare, nel 1990 Jim Adcock propose di consentire il sovraccarico dell'operatore .esattamente il modo in cui l'operatore è ->.

"I" in questa citazione è Bjarne Stroustrup. Non puoi essere più autorevole di così.

Se vuoi veramente capire il C++ (come in "perché è così"), dovresti assolutamente leggere questo libro.

1

È molto facile capire, se si passa attraverso il meccanismo interno della chiamata di funzione dell'operatore, Dire che un complesso di classe può avere due membri r per la parte reale e i per la parte immaginaria. Dire Complesso C1 (10,20), C2 (10,2) // assumiamo che ci sia già un costruttore di due argomenti all'interno della classe. Ora se scrivi C1 + C2 come istruzione, allora il compilatore prova a trovare la versione sovraccaricata dell'operatore + sul numero complesso. Ora supponiamo che io sovraccarico + operatore, quindi C1 + C2 tradotto internamente come c1.operator + (c2) Ora supponiamo per gli esseri del tempo che puoi sovraccaricare '.' operatore. così ora penso seguente chiamata C1.disp() // visualizzare il contenuto di un oggetto complesso Ora provate a rappresentare come una rappresentazione interna C1.operator. (------), cose completamente disordinato create. Questo è il motivo per cui non possiamo sovraccaricare '.' operator

+1

Alcune persone dicono che la traduzione interna non dovrebbe chiamare "operatore" sovraccarico – curiousguy