Pourquoi «ceci» est-il un pointeur et non une référence?


183

Je lisais les réponses à cette question pour et contre C ++ et j'ai eu ce doute en lisant les commentaires.

les programmeurs trouvent souvent déroutant que «ceci» soit un pointeur mais pas une référence. une autre confusion est la raison pour laquelle "hello" n'est pas de type std :: string mais s'évalue en un char const * (pointeur) (après la conversion d'un tableau en pointeur) - Johannes Schaub - litb 22 décembre 08 à 1:56

Cela montre seulement qu'il n'utilise pas les mêmes conventions que les autres langages (plus récents). - le dorfier 22 décembre 08 à 3:35

J'appellerais la chose "ceci" une question assez triviale cependant. Et oups, merci d'avoir détecté quelques erreurs dans mes exemples de comportement indéfini. :) Bien que je ne comprenne pas ce que les informations sur la taille ont à voir avec quoi que ce soit dans le premier. Un pointeur n'est tout simplement pas autorisé à pointer en dehors de la mémoire allouée - jalf 22 décembre 08 à 4:18

Est-ce un pointeur constant? - yesraaj 22 décembre 08 à 6:35

cela peut être constant si la méthode est const int getFoo () const; <- dans la portée de getFoo, "this" est constant, et donc en lecture seule. Cela évite les bogues et fournit un certain niveau de garantie à l'appelant que l'objet ne changera pas. - Doug T.Décembre 22 08 à 16:42

vous ne pouvez pas réaffecter «ceci». c'est-à-dire que vous ne pouvez pas faire "this = & other;", car c'est une rvalue. mais celui-ci est de type T *, pas de type T const. c'est-à-dire que c'est un pointeur non constant. si vous êtes dans une méthode const, alors c'est un pointeur vers const. T const. mais le pointeur lui-même est nonconst - Johannes Schaub - litb 22 décembre 08 à 17:53

pensez à "ceci" comme ceci: # définissez ceci (this_ + 0) où le compilateur crée "this_" comme pointeur vers l'objet et fait de "this" un mot-clé. vous ne pouvez pas attribuer "this" car (this_ + 0) est une rvalue. bien sûr, ce n'est pas comme ça (il n'y a pas de telle macro), mais cela peut aider à le comprendre - Johannes Schaub - litb 22 décembre 08 à 17:55

Ma question est la suivante: pourquoi thisun pointeur n'est-il pas une référence? Une raison particulière pour en faire un pointeur?


Quelques autres arguments pour lesquels thisêtre une référence aurait du sens:

  • Considérez à Item 1partir de More Effective C++ : utilisez des références quand il est garanti que nous avons un objet valide ie pas un NULL (mon interprétation).
  • De plus, les références sont considérées comme plus sûres que les pointeurs (car nous ne pouvons pas visser la mémoire avec un pointeur errant).
  • Troisièmement, la syntaxe pour accéder aux références ( .) est un peu plus agréable et plus courte que pour accéder aux pointeurs ( ->ou (*)).

5
@paulm Qu'est-ce que ce "hack" accomplirait réellement? N'évalue pas thistoujours true?
iFreilicht

6
@paulm Je ne pense pas que ce soit réellement du C ++ valide. L'appel de méthodes sur un nullptr à un objet entraîne un comportement non défini.
antred

5
@paulm Peut-être que cela fonctionne dans certains cas, mais imaginez si la méthode était virutale. Comment une recherche de v-table peut-elle être effectuée sans objet?
Jason Creighton

3
@paulm Si vous l'avez vu dans le code de production, abandonnez le navire! C'est UB.
Alice le

6
Je vais juste laisser ça ici ... (d'après afxwin2.inl de MFC):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
Christopher Oicles

Réponses:


176

Lors de la première évolution du langage, dans les premières versions avec de vrais utilisateurs, il n'y avait pas de références, seulement des pointeurs. Des références ont été ajoutées lorsque la surcharge d'opérateurs a été ajoutée, car elle nécessite des références pour fonctionner de manière cohérente.

L'une des utilisations de thisest pour un objet d'obtenir un pointeur sur lui-même. Si c'était une référence, il faudrait écrire &this. D'un autre côté, lorsque nous écrivons un opérateur d'affectation, nous devons le faire return *this, ce qui semblerait plus simple que return this. Donc, si vous aviez une ardoise vierge, vous pourriez argumenter dans les deux sens. Mais le C ++ a évolué progressivement en réponse aux commentaires d'une communauté d'utilisateurs (comme les choses les plus réussies). La valeur de la compatibilité ascendante dépasse totalement les avantages / inconvénients mineurs découlant du thisfait d' être une référence ou un pointeur.


4
Eh bien, il est également souvent utile pour un objet d'obtenir une référence à lui-même. Je dirais que c'est un usage plus courant. Quoi qu'il en soit, la raison principale est comme vous l'avez dit, les références n'existaient pas quand ils ont créé le pointeur «this».
jalf

20
Et, s'il s'agissait d'une référence, il serait difficile de surcharger operator &pour faire quelque chose d'utile. Il faudrait une syntaxe spéciale pour obtenir l'adresse de ce qui ne passerait pas operator &.
Omnifariable le

10
@conio - vous voudrez peut-être vérifier cela la prochaine fois que vous serez près d'un compilateur C ++! :) Quelque chose comme:int n = 5; int &r = n; int *p = &r; std::cout << *p;
Daniel Earwicker

14
@Omnifarious, vous pouvez écrire &reinterpret_cast<char&>(this);pour obtenir la véritable adresse de surcharge operator&(en fait, c'est en quelque sorte ce que boost::addressoffait).
Johannes Schaub - litb

9
Comme cela n'a pas vraiment de sens thisd'être nul, il me semble qu'une référence est vraiment plus appropriée.
Ponkadoodle

114

Un peu tard à la fête ... Tout droit sorti de la bouche du cheval, voici ce que Bjarne Stroustrup a à dire (qui est essentiellement repris ou tiré du livre "Design and Evolution of C ++"):

Pourquoi est-ce "this " n'est-il pas une référence?

Parce que "this" a été introduit en C ++ (vraiment en C avec Classes) avant l'ajout de références. Aussi, j'ai choisi " this" pour suivre l'utilisation de Simula, plutôt que l'utilisation (plus tardive) de "self" par Smalltalk.


2
Ouais, soi-même aurait été bien pour la cohérence avec d'autres langues, eh bien.
pilkch
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.