2012-03-07 24 views
5

Con trỏ this có được yêu cầu không? Tôi đoán bạn sẽ cần nó nếu bạn có chức năng đi qua xung quanh trường hợp của lớp được trỏ đến bởi this. Nhưng về mặt cài đặt/truy xuất/gọi/bất kỳ thành viên nào, là this luôn là tùy chọn?Khi nào 'điều này' được yêu cầu?

Tôi đã gắn thẻ C++ này vì đó là ngôn ngữ tôi tự hỏi, nhưng nếu ai đó có thể xác nhận rằng cấu trúc giống nhau đối với Java và các ngôn ngữ OO khác sử dụng con trỏ this, nó sẽ được đánh giá cao.

Trả lời

8

Bạn cần nó khi bạn có biến cục bộ có cùng tên chính xác với biến thành viên. Trong trường hợp này, biến cục bộ được gọi là bóng biến thành viên. Để đến biến thành viên trong tình huống này, bạn phải sử dụng this.

Một số người cho rằng thực hành tốt là đề cập rõ ràng rằng biến bạn đang sửa đổi là biến thành viên bằng cách sử dụng this mọi lúc, nhưng điều này không phải luôn luôn như vậy.

+0

Đối với C++ xem xét cuối cùng của bạn là đúng, nhưng đối với Java hoặc C#, nó không phải lúc nào cũng là ước – Geoffroy

+0

Đây là lý do tại sao bạn luôn tên thành viên của bạn các biến khác với các biến địa phương của bạn, ví dụ 'm_myVar' hoặc' myVar_', v.v. Vì việc sử dụng 'this' không được thực thi nên hầu hết các dự án chọn tham gia buộc một tiêu chuẩn đặt tên trên các biến thành viên. –

+1

Tôi sẽ không nói đó là hình thức tốt để sử dụng 'này' tất cả các thời gian. Chỉ sử dụng nó nếu có tên bóng tối. Thông thường các bóng tối cũng có thể tránh được. –

11

Có ba trường hợp tôi có thể nghĩ:

Khi bạn chỉ muốn vượt qua một con trỏ tới lớp hiện tại:

class B; 
struct A { 
    B* parent_; 
    A(B* parent) : parent_(parent) {} 
}; 

struct B { 
    A* a; 
    B() : a(new A(this)) {} 
}; 

Trong một constructor hoặc hàm thành viên, trong đó một thành viên là bị che khuất bởi một đối số:

struct A { 
    int a; 
    void set_a(int a) { this->a = a; } 
}; 

Ở đây, biến thành viên "a" bị bóng mờ bởi argum ent "a", vì vậy this-> được sử dụng để truy cập vào thành viên thay vì đối số.

(ví dụ trên đã chỉnh sửa để có một chức năng chứ không phải là nhà xây dựng, vì bạn sẽ không bình thường gán theo cách này trong một constructor)


Khi truy cập vào một/bảo vệ biến thành viên công cộng hoặc chức năng trong một lớp cơ sở của một lớp mẫu

template <class T> 
struct A { 
    int a; 
}; 

template <class T> 
struct B : public A<T> { 
    int f() { return this->a; } 
} 

đây, a một mình sẽ không có một tên phụ thuộc, do đó trình biên dịch sẽ mong đợi để tìm một tuyên bố của nó trong B hoặc một cơ sở của B mà không phụ thuộc trên T. Thêm this-> làm cho việc tìm kiếm phụ thuộc vào loại this và do this là loại phụ thuộc, nên tra cứu a cho đến khi f() được khởi tạo.

Người ta có thể viết return A::a thay vì return this->a, nhưng khi có nhiều cơ sở, dù trực tiếp hay gián tiếp, sử dụng this-> linh hoạt hơn. Cú pháp thay thế này cũng được giới hạn cho các biến thành viên và các hàm không phải ảo - nếu nó được sử dụng với một hàm ảo, hàm sẽ được gọi trực tiếp thay vì thực hiện cuộc gọi hàm ảo.

+0

Bạn luôn có thể sử dụng classname :: variablename để truy cập nó, vì vậy điều này có thể được sử dụng cho nó, nhưng nó không cần thiết. – PlasmaHH

+0

@PlasmaHH Vâng, tôi đã giải thích câu hỏi là "trong tình huống nào đang viết 'cái này' không thừa" thay vì "trong tình huống nào đang viết 'đây' cách duy nhất để đạt được điều gì đó" – je4d

+1

Thực tế chỉ ví dụ đầu tiên của bạn là chính xác , đối với hai người kia, việc sử dụng 'this' là tùy chọn. Trong ví dụ thứ hai của bạn, sử dụng danh sách khởi tạo ctor là thành ngữ C++ và sẽ không có vấn đề mơ hồ, ví dụ: 'A :: A (int a): a (a) {}' là hợp lệ và không rõ ràng (đối với trình biên dịch ít nhất). –

-1

đôi khi "này" là bắt buộc, có thể khi bạn đang truyền đối tượng của mình sang một hàm khác. nhìn vào mã này C# (để mở một dạng phương thức với bố mẹ này)

Form1 f = new Form(); 
f.ShowDialog(this); 
+0

Điều này không giống như C++. – svick

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