c++ differenza - Perché 'questo' è un puntatore e non un riferimento?




puntatori record (5)

Stavo leggendo le risposte a questa domanda C ++ pro e contro e ho ottenuto questo dubbio mentre leggevo i commenti.

i programmatori trovano spesso confuso che "questo" sia un puntatore ma non un riferimento. un'altra confusione è il motivo per cui "ciao" non è di tipo std :: string ma restituisce un char const * (puntatore) (dopo la conversione da matrice a puntatore) - Johannes Schaub - litb 22 dic08 alle 1:56

Questo dimostra che non usa le stesse convenzioni delle altre lingue (successive). - Le Dorfier 22 dicembre 08 alle 3:35

Chiamerei la "questa" cosa piuttosto banale. E ops, grazie per aver catturato alcuni errori nei miei esempi di comportamento indefinito. :) Sebbene non capisco quali informazioni sulla dimensione abbiano a che fare con qualcosa nel primo. Un puntatore non può semplicemente puntare all'esterno della memoria allocata - jalf 22 dicembre 08 alle 4:18

È un poeta costante? - yesraaj 22 dicembre 08 alle 06:35

questo può essere costante se il metodo è const int getFoo () const; <- nell'ambito di getFoo, "questo" è costante ed è quindi di sola lettura. Questo impedisce bug e fornisce un certo livello di garanzia al chiamante che l'oggetto non cambierà. - Doug T. 22 dicembre 08 alle 16:42

non puoi riassegnare "questo". cioè non puoi fare "this = & other;", perché questo è un valore. ma questo è di tipo T *, non di tipo T const. cioè è un puntatore non costante. se sei in un metodo const, allora è un puntatore a const. T const. ma il pointer stesso non è coerente - Johannes Schaub - litb 22 dicembre 08 alle 17:53

pensa a "questo" in questo modo: #define this (this_ + 0) dove il compilatore crea "this_" come puntatore all'oggetto e rende "this" una parola chiave. non puoi assegnare "questo" perché (questo_ + 0) è un valore. ovviamente non è così (non c'è una tale macro), ma può aiutare a capirlo - Johannes Schaub - litb 22 dicembre 08 alle 17:55

La mia domanda è, perché this è un puntatore e non un riferimento? Qualche ragione particolare per renderlo un puntatore?

Alcuni ulteriori argomenti per cui this riferimento sarebbe sensato:

  • Considera l' Item 1 da More Effective C++ : usa i riferimenti quando è garantito che abbiamo un oggetto valido, cioè non un NULL (la mia interpretazione).
  • Inoltre, i riferimenti sono considerati più sicuri dei puntatori (perché non possiamo rovinare la memoria con un puntatore vagante).
  • In terzo luogo, la sintassi per accedere ai riferimenti ( . ) È un po 'più bella e più corta dell'accesso ai puntatori ( -> o (*) ).

Answers

Indipendentemente da come siamo arrivati ​​qui, penso che sia una fortuna che questo sia un puntatore e non un riferimento in quanto ciò aiuta a "dare un senso" che è possibile eliminarlo :

void A::f () {
  delete &this;
}

Penso che questo sia un caso in cui senza necessariamente essere di progettazione, il C ++ è meglio così com'è.


Un po 'tardi per la festa ... Direttamente dalla bocca del cavallo, ecco cosa Bjarne Stroustrup ha da dire (che è essenzialmente ripetuto nel libro "Design ed Evolution of C ++"):

Perché "questo" non è un riferimento?

Perché "questo" è stato introdotto in C ++ (veramente in C con Classi) prima che i riferimenti venissero aggiunti. Inoltre, ho scelto "questo" per seguire l'uso di Simula, piuttosto che l'uso (successivo) di Smalltalk di "sé".


Lo standard C ++ lo afferma

9.3.2 / 1

Nel corpo di una funzione membro nonstatica (9.3), la parola chiave è un'espressione non a valore lue il cui valore è l'indirizzo dell'oggetto per cui viene chiamata la funzione. Il tipo di questo in una funzione membro di una classe X è X *. Se la funzione membro è dichiarata const, il tipo di questo è const X *, se la funzione membro è dichiarata volatile, il tipo di questo è X volatile, e se la funzione membro è dichiarata const volatile, il tipo di questo è const volatile X *.

Ma in altri riferimenti, è stato trovato qualcos'altro .. così qualcuno ha preso l'iniziativa e ha sparato una mail a Mr. Stroustrup . La conversazione che segue può essere trovata here .


Quando il linguaggio si stava evolvendo per la prima volta, nelle prime versioni con utenti reali, non c'erano riferimenti, solo riferimenti. I riferimenti sono stati aggiunti quando è stato aggiunto il sovraccarico dell'operatore, in quanto richiede che i riferimenti funzionino in modo coerente.

Uno degli usi di this è che un oggetto ottenga un puntatore a se stesso. Se fosse un riferimento, dovremmo scrivere &this . D'altra parte, quando scriviamo un operatore di assegnamento dobbiamo return *this , che sembrerebbe più semplice come return this . Quindi, se tu avessi una lista vuota, potresti discuterne in entrambi i modi. Ma C ++ si è evoluto gradualmente in risposta al feedback di una comunità di utenti (come la maggior parte delle cose di successo). Il valore della retrocompatibilità travolge totalmente i piccoli vantaggi / svantaggi derivanti dal fatto che this tratti di un riferimento o di un puntatore.


I modelli devono essere utilizzati nelle intestazioni perché il compilatore deve istanziare diverse versioni del codice, in base ai parametri dati / dedotti per i parametri del modello. Ricorda che un modello non rappresenta direttamente il codice, ma un modello per diverse versioni di quel codice. Quando si compila una funzione non modello in un file .cpp , si compila una funzione / classe concreta. Questo non è il caso per i modelli, che possono essere istanziati con tipi diversi, vale a dire, il codice concreto deve essere emesso quando si sostituiscono i parametri del modello con tipi concreti.

C'era una funzionalità con la parola chiave export che doveva essere utilizzata per la compilazione separata. La funzione di export è deprecata in C++11 e, AFAIK, solo un compilatore l'ha implementata. Non dovresti usare l' export . La compilazione separata non è possibile in C++ o C++11 ma forse in C++17 , se i concetti lo fanno, potremmo avere un modo di compilazione separata.

Per ottenere una compilazione separata, deve essere possibile un controllo del corpo del modello separato. Sembra che una soluzione sia possibile con i concetti. Dai uno sguardo a questo paper presentato di recente alla riunione del comitato standard. Penso che questo non sia l'unico requisito, dal momento che è ancora necessario creare un'istanza di codice per il codice del modello nel codice utente.

Il problema di compilazione separato per i modelli credo sia anche un problema che si presenta con la migrazione ai moduli, che è attualmente in lavorazione.





c++ pointers reference this c++-faq