2009-03-14 58 views
143

Tôi đã đọc câu trả lời cho câu hỏi này C++ pros and cons và nhận được sự nghi ngờ này khi đọc nhận xét.Tại sao 'this' là một con trỏ chứ không phải là một tham chiếu?

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

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 Dec 22 '08 at 3:35

Tôi gọi điều này là một vấn đề khá tầm thường. Và oops, cảm ơn vì đã bắt được một vài lỗi trong ví dụ về hành vi không xác định của tôi. :) Mặc dù tôi không hiểu những thông tin về kích thước đã làm với bất cứ điều gì trong lần đầu tiên. Một con trỏ đơn giản là không được phép trỏ ra ngoài bộ nhớ được cấp phát - jalf Dec 22 '08 at 4:18

Đây có phải là một nhà thơ không ngừng? - yesraaj Ngày 22 tháng 12 năm 2008 tại 6:35

điều này có thể không đổi nếu phương thức là const int getFoo() const; < - trong phạm vi của getFoo, "this" 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. Dec 22 '08 at 16:42

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

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

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


Một số lập luận thêm lý do tại sao this được một tài liệu tham khảo sẽ có ý nghĩa:

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

Vì vậy, mọi người có thể thực hiện các hacks xấu xí như void foo :: something() {if (this) stuff(); }} – paulm

+3

@paulm "hack" này thực sự sẽ thực hiện điều gì? Không phải 'điều này' luôn luôn đánh giá là' đúng'? – iFreilicht

+0

foo * instance = nullptr; foo-> một cái gì đó(); // Bây giờ nếu (this) == false – paulm

Trả lời

142

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

Một trong những cách sử dụng của this là để một đối tượng có được con trỏ.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 toán tử gán, chúng ta phải return *this, trông đơn giản hơn là return this. Vì vậy, nếu bạn có một phiến đá trắng, bạn có thể tranh luận nó theo một trong hai cách. Nhưng C++ đã dần tiến hóa theo phản hồi từ mộ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 tính tương thích ngược hoàn toàn áp đảo các ưu điểm/nhược điểm nhỏ xuất phát từ this là một tham chiếu hoặc một con trỏ.

+3

Vâng, 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 đó là cách sử dụng phổ biến hơn. Dù sao, lý do chính là như bạn đã nói, tài liệu tham khảo không tồn tại khi họ tạo ra con trỏ 'này'. – jalf

+0

Nếu 'điều này' là một tham chiếu, việc sử dụng chính của điều này có lẽ sẽ là 'this.member' thay vì 'this-> member', vì vậy bạn sẽ không cần ký hiệu và hầu hết thời gian. –

+1

tôi hoàn toàn đồng ý với đoạn đầu tiên của bạn. và tôi nghĩ rằng việc sử dụng chính của nó là lấy địa chỉ của đối tượng. nhưng tại sao lại cần một con trỏ? tham chiếu sẽ làm tốt như nhau và sẽ làm tốt hơn cho các trường hợp khác như "this.foo" và "swap (this, bar)" –

88

Một chút muộn để đảng ... Trực tiếp từ miệng của ngựa, here's what Bjarne Stroustrup has to say (mà chủ yếu là lặp đi lặp lại hoặc lấy từ "Thiết kế và Sự phát triển của C++" cuốn sách):

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

Vì "điều này" đã được đưa vào C++ (thực sự thành C với Lớp học) trước khi các tham chiếu được thêm vào. Ngoài ra, tôi đã chọn "này" để theo dõi việc sử dụng Simula, thay vì sử dụng Smalltalk (sau này) của "self".

+0

Vâng, bản thân tôi sẽ rất tốt cho sự nhất quán với các ngôn ngữ khác, tốt thôi. – pilkch

-3

Bất kể thế nào chúng ta có ở đây, tôi nghĩ đó là may mắn mà đây là một con trỏ và không phải là một tài liệu tham khảo như thế này giúp nó "có ý nghĩa" mà bạn có thể xóa nó:

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

Tôi nghĩ rằng đây là một trường hợp mà không nhất thiết phải là do thiết kế, C++ là tốt hơn vì nó được.

+45

Tôi muốn nói đó là một lý lẽ rất tốt cho lý do tại sao nó phải là một tham chiếu ... Các lớp học thường không phải tự xóa mình. – jalf

+5

Có thể không nói chung - nhưng có những ví dụ mà bạn muốn nó xảy ra. Ví dụ như một con trỏ thông minh xâm nhập. –

+15

Trong những trường hợp đó, bạn chỉ có thể viết 'xóa &this; 'như được hiển thị, mặc dù :) Tôi nghĩ về nó như với các kiểu mới và chuyển đổi ẩn: Làm cho các trường hợp xấu xí cần nhiều ký tự hơn và làm cho các trường hợp đẹp hơn cần ít ký tự hơn:) –

-2

C++ bang tiêu chuẩn mà

9.3.2/1

Trong cơ thể của một không tĩnh hàm thành viên (9,3) , từ khóa này là một biểu phi vế trái có giá trị là địa chỉ của đối tượng mà trong đó chức năng được gọi. Các loại điều này trong một chức năng thành viên của một lớp X là X *. Nếu hàm thành viên là được khai báo const, loại này là const X *, nếu hàm thành viên là được khai báo dễ bay hơi, loại này là dễ bay hơi X * và nếu thành viên chức năng được khai báo const volatile, loại hình này là const dễ bay hơi X *.

Nhưng trong các tài liệu tham khảo khác, nó đã được tìm thấy một cái gì đó khác .. vì vậy ai đó đã chủ động và gửi thư đến Mr. Stroustrup. Bạn có thể tìm thấy cuộc hội thoại theo sau here.

+0

(A) Giao dịch với một khía cạnh khác của 'this'; nó không liên quan đến câu hỏi được hỏi. (B) Bỏ qua nó không liên quan, bạn nên trích dẫn liên kết; SE cau mày khi có câu trả lời chỉ liên kết.Tất cả các câu trả lời của chính nó chứa là một trích dẫn không liên quan từ tiêu chuẩn, không phải bất kỳ sắc thái nào. –

Các vấn đề liên quan