Il sovraccarico di accesso ai membri operatori ->, .* (C++)

Capisco più l’overload dell’operatore, con l’eccezione del membro di accedere agli operatori ->, .*, ->* etc.

In particolare, ciò che è passato per queste funzioni di operatore, e quello che dovrebbe essere restituito?

Come funziona la funzione di operatore (ad es. operator->(...) ) sa che cosa il membro è riferito? Si, si può sapere? Lo fa anche bisogno di sapere?

Infine, ci sono const considerazioni che devono essere presi in considerazione? Per esempio, quando il sovraccarico di qualcosa di simile operator[], in genere è necessario disporre di un const e non-const versione. Stati di accesso gli operatori richiedono const e non-const versioni?

  • Credo che il sopra C++-Faq tocca tutte le Q chiesto nel precedente D.
  • const e nonconst versioni di operator-> non sono necessari, ma entrambi possono essere utili.
  • Vedi anche: yosefk.com/c++fqa/operator.html
  • Le FAQ non spiega come sovraccarico ->* e .*. Esso, infatti, non menziona neppure loro! Sento che sono rare a trovarsi in una FAQ, ma avrei volentieri il link di questa domanda da FAQ. si Prega di non chiudere questo come una vittima delle FAQ!
  • Ho appena completamente non è riuscito a trovare un link a questa questione dal tuo (impressionante) FAQ, e si è conclusa con la richiesta di un duplicato domanda. Si potrebbe rendere più evidente? (mi scuso se è già evidente).
InformationsquelleAutor Bingo | 2012-01-08

 

5 Replies
  1. 135

    ->

    Questa è l’unica veramente difficile. Deve essere una funzione membro non static, e non accetta argomenti. Il valore restituito viene utilizzato per eseguire il socio di ricerca.

    Se il valore di ritorno è un altro oggetto di tipo classe, non un puntatore, quindi il membro successivo di ricerca è anche gestito da un operator-> funzione. Questo è chiamato il “drill-down “comportamento”. La lingua catene insieme il operator-> chiamate fino a quando l’ultimo restituisce un puntatore.

    struct client
        { int a; };
    
    struct proxy {
        client *target;
        client *operator->() const
            { return target; }
    };
    
    struct proxy2 {
        proxy *target;
        proxy &operator->() const
            { return * target; }
    };
    
    void f() {
        client x = { 3 };
        proxy y = { & x };
        proxy2 z = { & y };
    
        std::cout << x.a << y->a << z->a; //print "333"
    }

    ->*

    Questo è solo complicato dal fatto che non c’è niente di speciale su di esso. Il non overload versione richiede un oggetto di un puntatore a tipo di classe sul lato sinistro e un oggetto di un puntatore a membro di tipo a destra. Ma quando è sovraccarico, puoi prendere un qualsiasi argomento che ti piace e restituire tutto quello che vuoi. Non hanno nemmeno bisogno di essere un membro non static.

    In altre parole, questo è solo un normale operatore binario come +, -, e /. Vedi anche: Sono operatore libero->* sovraccarichi male?

    .* e .

    Questi non possono essere sovraccaricati. C’è già un built-in senso lato sinistro è di tipo classe. Forse si poteva fare un po ‘ di senso di essere in grado di definire un puntatore sul lato sinistro, ma il design di un linguaggio comitato ha deciso che sarebbe più confusione che utile.

    Sovraccarico ->, ->*, ., e .* può compilare solo nei casi in cui un’espressione potrebbe essere definito, esso non potrà mai cambiare il significato di un’espressione che sarebbe valida, senza sovraccarico.

    • La tua ultima affermazione non è del tutto vero. Per esempio, si può sovraccaricare il new operatore, anche se è valido anche quando non è in sovraccarico.
    • beh, new è sempre sovraccarico, o di sovraccaricare le regole non sono realmente applicabili (13.5/5: L’allocazione e la deallocazione funzioni, nuovo operatore, operatore new[], eliminazione di operatore e l’operatore delete[], sono descritti completamente in 3.7.4. Gli attributi e le restrizioni presenti nel resto del presente comma non si applicano a loro a meno che non sia esplicitamente dichiarato nel 3.7.4.) Ma il sovraccarico unario & o binario &&, ||, o ,, o l’aggiunta di sovraccarichi di operator=, o il sovraccarico di tutto per un ruolo di tipo di enumerazione, può cambiare un’espressione del significato. Precisa, grazie!
  2. 31

    Operatore -> è speciale.

    “Altre operazioni atipiche vincoli: deve restituire un oggetto (o un riferimento a un oggetto), che ha anche un pointer dereference operatore, o deve restituire un puntatore che può essere utilizzato per selezionare il tipo di pointer dereference operatore freccia punta verso.”
    Bruce Eckel: il Pensiero CPP Vol-una : operatore->

    Funzionalità extra è fornito per comodità, così non è necessario chiamare

    a->->func();

    Si può semplicemente fare:

    a->func();

    Che rende operatore -> diverso dall’altro operatore sovraccarichi.

    • Questa risposta merita più credito, è possibile scaricare Eckel libro da quel link e le informazioni nel capitolo 12 di volume uno.
    • il link è rotto
  3. 25

    Non è possibile sovraccarico membro di accedere . (cioè la seconda parte di quello che -> fa). Tuttavia, è possibile sovraccarico unario dereferenziazione operatore * (cioè la prima parte di quello che -> fa).

    Il C++ -> operatore è praticamente l’unione di due passi e questo è evidente se si pensa che x->y è equivalente a (*x).y. Il C++ permette di personalizzare ciò che a che fare con il (*x) parte quando x è un’istanza della classe.

    Semantico per -> sovraccarico è un po ‘ strano perché il C++ permette di restituire un normale puntatore (che sarà utilizzato per trovare l’oggetto appuntito) o per la restituzione di un’istanza di un’altra classe, se questa classe fornisce un -> operatore. Quando in questo secondo caso la ricerca per l’privo di riferimenti oggetto continua da questa nuova istanza.

    • Grande spiegazione!!! Immagino che significa stessa per ->*, in quanto è equivalente a forma di (*x).* ?
  4. 10

    Il -> operatore non sa cos’è membro viene sottolineato, fornisce solo un oggetto per eseguire il membro effettivo accesso.

    Inoltre, non vedo alcun motivo per cui non è possibile fornire const e non-const versioni.

  5. 6

    Quando si esegue l’overload dell’operatore->() (senza argomenti sono passati di qui), ciò che il compilatore fa effettivamente sta chiamando -> ricorsivamente fino a quando si restituisce un puntatore a un tipo. Si utilizza quindi la corretta membro del metodo.

    Questo è utile, ad esempio, per creare un puntatore intelligente di classe che incapsula il puntatore effettivo. L’overload dell’operatore-> è chiamato, fa quello che fa (es. blocco per filo di sicurezza), restituisce il puntatore interno e quindi il compilatore chiama -> per questo puntatore interno.

    Come per constness ‘- e ‘ stato risposto nei commenti e altre risposte (si possono, e devono, fornire sia).

Lascia un commento