Tại sao 'đây' là một con trỏ và không phải là một tài liệu tham khảo?


182

Tôi đã đọc câu trả lời cho câu hỏi này C ++ ưu và nhược điểm và có nghi ngờ này trong khi đọc các bình luận.

Các lập trình viên thường thấy khó hiểu rằng "cái này" là một con trỏ nhưng không phải là một tham chiếu. một sự nhầm lẫn khác là tại sao "hello" không phải là kiểu std :: string mà là đánh giá thành một char const * (con trỏ) (sau khi chuyển đổi mảng thành con trỏ) - Johannes Schaub - litb ngày 22 tháng 12 '08 lúc 1:56

Điều đó chỉ cho thấy rằng nó không sử dụng các quy ước giống như các ngôn ngữ khác (sau này). - le dorfier ngày 22 tháng 12 năm 08 lúc 3:35

Tôi sẽ gọi điều "này" là một vấn đề khá nhỏ. Và rất tiếc, cảm ơn vì đã bắt được một vài lỗi trong các ví dụ về hành vi không xác định của tôi. :) Mặc dù tôi không hiểu thông tin về kích thước có liên quan gì với cái đầu tiên. Một con trỏ chỉ đơn giản là không được phép chỉ ra bên ngoài bộ nhớ được phân bổ - jalf 22 tháng 12 '08 lúc 4:18

Đây có phải là một nhà thơ không đổi? - yesraaj ngày 22 tháng 12 năm 08 lúc 6:35

điều này có thể là hằng số nếu phương thức là const int getFoo () const; <- trong phạm vi của getFoo, "cái này" là hằng số, và do đó chỉ đọc. Điều này ngăn ngừa lỗi và cung cấp một số mức bảo đảm cho người gọi rằng đối tượng sẽ không thay đổi. - Doug T. ngày 22 tháng 12 năm 08 lúc 16:42

bạn không thể gán lại "cái này". tức là bạn không thể thực hiện "this = & other;", bởi vì đây là giá trị. nhưng đây là loại T *, không phải loại T const. tức là nó là một con trỏ không đổi. nếu bạn đang ở trong một phương thức const, thì đó là một con trỏ tới const. T const. nhưng bản thân con trỏ là nonconst - Johannes Schaub - litb ngày 22 tháng 12 '08 lúc 17:53

hãy nghĩ về "this" như thế này: #define this (this_ + 0) trong đó trình biên dịch tạo "this_" làm con trỏ tới đối tượng và biến "this" thành một từ khóa. bạn không thể gán "cái này" bởi vì (this_ + 0) là một giá trị. tất nhiên đó không phải là như vậy (không có macro như vậy), nhưng nó có thể giúp hiểu nó - Johannes Schaub - litb ngày 22 tháng 12 '08 lúc 17:55

Câu hỏi của tôi là, tại sao thismột con trỏ không phải là một tài liệu tham khảo? Bất kỳ lý do cụ thể để làm cho nó một con trỏ?


Một số tranh luận thêm tại sao thislà một tài liệu tham khảo sẽ có ý nghĩa:

  • Xem xét Item 1từ More Effective C++ : sử dụng tài liệu tham khảo khi được đảm bảo rằng chúng tôi có một đối tượng hợp lệ, tức là không phải là NULL (cách giải thích của tôi).
  • Hơn nữa, các tài liệu tham khảo được coi là an toàn hơn con trỏ (vì chúng ta không thể vặn bộ nhớ lên bằng một con trỏ đi lạc).
  • Thứ ba, cú pháp để truy cập tài liệu tham khảo ( .) đẹp hơn một chút và ngắn hơn so với truy cập con trỏ ( ->hoặc (*)).

5
@paulm "hack" này thực sự sẽ làm gì? Không phải thislúc nào cũng đánh giá true?
iFreilicht

6
@paulm Tôi không nghĩ đó là C ++ thực sự hợp lệ. Gọi các phương thức trên nullptr đến một đối tượng dẫn đến hành vi không xác định.
antred

5
@paulm Có thể nó hoạt động trong một số trường hợp, nhưng hãy tưởng tượng nếu phương pháp này là độc hại. Làm thế nào một tra cứu bảng v có thể được thực hiện mà không có đối tượng?
Jason Creighton

3
@paulm Nếu bạn đã thấy nó trong mã sản xuất, hãy từ bỏ tàu! Đó là UB.
Alice

6
Tôi chỉ sẽ rời này đây ... (từ afxwin2.inl MFC của):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
Christopher Oicles

Câu trả lời:


175

Khi ngôn ngữ lần đầu tiên phát triển, trong các phiên bản đầu tiên với người dùng thực sự, không có tài liệu tham khảo, chỉ có con trỏ. Các tham chiếu đã được thêm vào khi quá tải toán tử được thêm vào, vì nó yêu cầu các tham chiếu để hoạt động ổn định.

Một trong những cách sử dụng thislà để một đối tượng lấy một con trỏ tới chính nó. Nếu đó là một tài liệu tham khảo, chúng tôi sẽ phải viết &this. Mặt khác, khi chúng ta viết một toán tử gán, chúng ta return *thissẽ trông đơn giản hơn return this. Vì vậy, nếu bạn có một bảng trống, bạn có thể tranh luận một trong hai cách. Nhưng C ++ đã phát triển dần dần để đáp ứng với phản hồi từ cộng đồng người dùng (như hầu hết những điều thành công). Giá trị của khả năng tương thích ngược hoàn toàn áp đảo những lợi thế / bất lợi nhỏ xuất phát từ thisviệc là một tham chiếu hoặc một con trỏ.


4
Chà, nó cũng thường hữu ích cho một đối tượng để có được một tham chiếu đến chính nó. Tôi muốn nói rằng đó là một cách sử dụng phổ biến hơn. Dù sao, lý do chính là như bạn đã nói, các tài liệu tham khảo đã không tồn tại khi họ tạo con trỏ 'cái này'.
jalf

20
Và, nếu đây là một tài liệu tham khảo, sẽ rất khó để quá tải operator &để làm bất cứ điều gì hữu ích. Sẽ phải có một số cú pháp đặc biệt để có được địa chỉ này sẽ không được thông qua operator &.
Omnifarious

10
@conio - bạn có thể muốn kiểm tra xem lần tới khi bạn ở gần trình biên dịch C ++! :) Một cái gì đó như:int n = 5; int &r = n; int *p = &r; std::cout << *p;
Daniel Earwicker

14
@Omnifarious bạn có thể viết &reinterpret_cast<char&>(this);để có được địa chỉ thực sự cho quá tải operator&(trên thực tế, đây là loại những gì boost::addressoflàm).
Julian Schaub - litb

9
Vì nó không thực sự có ý nghĩa gì đối thisvới null, nên đối với tôi, một tài liệu tham khảo thực sự phù hợp hơn.
Ponkadoodle

114

Đến bữa tiệc muộn một chút ... Ngay từ miệng ngựa, đây là những gì Bjarne Stroustrup nói (về cơ bản được lặp lại trong hoặc lấy từ cuốn sách "Thiết kế và tiến hóa của C ++"):

Tại sao "cái này" không phải là một tài liệu tham khảo?

Bởi vì "cái này" đã được đưa vào C ++ (thực sự vào C với Classes) trước khi các tài liệu tham khảo được thêm vào. Ngoài ra, tôi đã chọn "cái này" để theo dõi việc sử dụng Simula, thay vì sử dụng "bản thân" của Smalltalk.


2
Vâng, bản thân sẽ rất tốt khi thống nhất với các ngôn ngữ khác, ồ tốt.
pilkch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.