Dlaczego „to” jest wskaźnikiem, a nie odniesieniem?

183

Czytałem odpowiedzi na to pytanie za i przeciw C ++ i miałem wątpliwości podczas czytania komentarzy.

programiści często uważają za mylące, że „to” jest wskaźnikiem, ale nie odniesieniem. Kolejnym nieporozumieniem jest to, dlaczego „hello” nie jest typu std :: string, ale przekształca się w char const * (wskaźnik) (po konwersji tablicy na wskaźnik) - Johannes Schaub - litb 22 grudnia 2008 o 1:56

To pokazuje tylko, że nie używa tych samych konwencji, co inne (późniejsze) języki. - le dorfier 22 grudnia 08 o 3:35

Nazwałbym to „tym” dość trywialnym problemem. I ups, dzięki za złapanie kilku błędów w moich przykładach niezdefiniowanego zachowania. :) Chociaż nie rozumiem, co informacje o rozmiarze mają wspólnego z czymkolwiek w pierwszym. Wskaźnik po prostu nie może wskazywać poza przydzieloną pamięć - czerwiec 22 '08 o 4:18

Czy to jest stały poiner? - yesraaj, 22 grudnia 08 o 6:35

może to być stałe, jeśli metoda jest const int getFoo () const; <- w zakresie getFoo „to” jest stałe i dlatego jest tylko do odczytu. Zapobiega to błędom i zapewnia pewną gwarancję dzwoniącemu, że obiekt się nie zmieni. - Doug T., 22 grudnia08 o 16:42

nie można ponownie przypisać „tego”. tzn. nie możesz zrobić „this = & other;”, ponieważ jest to wartość. ale to jest typu T *, a nie typu T const. tzn. jest to niestały wskaźnik. jeśli używasz metody const, to jest to wskaźnik do const. T const. ale sam wskaźnik jest niekonsekwentny - Johannes Schaub - litb 22 grudnia 08 o 17:53

pomyśl o „tym” w ten sposób: # zdefiniuj to (this_ + 0), w którym kompilator tworzy „this_” jako wskaźnik do obiektu i czyni z tego słowa kluczowego. nie możesz przypisać „tego”, ponieważ (this_ + 0) to wartość. oczywiście tak nie jest (nie ma takiego makra), ale może pomóc to zrozumieć - Johannes Schaub - litb 22 grudnia 08 17:55

Moje pytanie brzmi: dlaczego thiswskaźnik nie jest odnośnikiem? Czy jest jakiś konkretny powód, aby uczynić go wskaźnikiem?


Kolejne argumenty, dlaczego thisbycie referencją ma sens:

  • Rozważmy Item 1z More Effective C++ : stosowania odniesień, gdy jest zagwarantowane, że mamy ważny obiekt IE nie NULL (moja interpretacja).
  • Co więcej, odniesienia są uważane za bezpieczniejsze niż wskaźniki (ponieważ nie możemy zepsuć pamięci za pomocą bezpańskiego wskaźnika).
  • Po trzecie, składnia dostępu do referencji ( .) jest nieco ładniejsza i krótsza niż dostęp do wskaźników ( ->lub (*)).
Naveen
źródło
5
@paulm Co faktycznie zrobiłby ten „hack”? Nie thiszawsze ocenia się true?
iFreilicht
6
@paulm Nie sądzę, że to właściwie poprawny C ++. Wywołanie metod na obiekcie nullptr do obiektu powoduje niezdefiniowane zachowanie.
antred
5
@paulm Może to działa w niektórych przypadkach, ale wyobraź sobie, że metoda była wirusowa. Jak można przeprowadzić wyszukiwanie w tabeli V bez obiektu?
Jason Creighton
3
@paulm Jeśli widziałeś go w kodzie produkcyjnym, porzuć statek! To jest UB.
Alice
6
Zostawię to tutaj ... (z afxwin2.inl MFC):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
Christopher Oicles

Odpowiedzi:

176

Kiedy język ewoluował po raz pierwszy, we wczesnych wersjach z prawdziwymi użytkownikami nie było żadnych odniesień, tylko wskaźniki. Odniesienia zostały dodane, gdy dodano przeciążenie operatora, ponieważ wymaga to odniesienia do konsekwentnej pracy.

Jednym z zastosowań thisjest uzyskanie przez obiekt wskaźnika do siebie. Gdyby to było odniesienie, musielibyśmy napisać &this. Z drugiej strony, kiedy piszemy operatora przypisania, musimy return *this, co wyglądałoby na prostsze return this. Więc jeśli miałeś pustą kartę, możesz argumentować w obu kierunkach. Ale C ++ ewoluował stopniowo w odpowiedzi na opinie społeczności użytkowników (jak najbardziej udane rzeczy). Wartość zgodności wstecznej całkowicie przytłacza drobne zalety / wady wynikające z thisbycia referencją lub wskaźnikiem.

Daniel Earwicker
źródło
4
Cóż, często przydaje się obiektowi odniesienie do siebie. Powiedziałbym, że jest to bardziej powszechne użycie. W każdym razie główny powód jest taki, jak powiedziałeś, odniesienia nie istniały, gdy utworzyli wskaźnik „ten”.
lipiec
20
A jeśli byłoby to odniesienie, trudno byłoby przeładować, operator &aby zrobić coś pożytecznego. Musi istnieć specjalna składnia, aby uzyskać adres tego, który nie przejdzie operator &.
Wszechobecny
10
@conio - możesz sprawdzić, czy następnym razem będziesz w pobliżu kompilatora C ++! :) Coś w stylu:int n = 5; int &r = n; int *p = &r; std::cout << *p;
Daniel Earwicker
14
@Omnifarious możesz napisać, &reinterpret_cast<char&>(this);aby uzyskać prawdziwy adres do przeciążenia operator&(w rzeczywistości jest to coś, co boost::addressofdziała).
Johannes Schaub - litb
9
Ponieważ tak naprawdę nie ma sensu thisbyć zerowym, wydaje mi się, że odniesienie jest naprawdę bardziej odpowiednie.
Ponkadoodle,
114

Trochę późno na imprezę ... Prosto z pyska konia, oto, co ma do powiedzenia Bjarne Stroustrup (co jest zasadniczo powtórzone lub zaczerpnięte z książki „Design and Evolution of C ++”):

Dlaczego „ this” nie jest odnośnikiem?

Ponieważ „to” zostało wprowadzone do C ++ (tak naprawdę do C z klasami) przed dodaniem referencji. Wybrałem też „ this”, aby podążać za użyciem Simuli, zamiast (późniejszego) użycia „ja” w Smalltalk.

Michael Burr
źródło
2
Tak, jaźń byłaby miła ze względu na spójność z innymi językami, no cóż.
pilkch