2013-05-11 27 views
7

Tôi là khá mới với C++, và tôi không hiểu những gì con trỏ this làm trong các tình huống sau:Con trỏ 'này' là gì?

void do_something_to_a_foo(Foo *foo_instance); 


void Foo::DoSomething() 
{ 
    do_something_to_a_foo(this); 
} 

Tôi túm lấy mà từ bài của người khác ở đây.

Điều gì làm this trỏ tới? Tôi bối rối. Hàm không có đầu vào, vì vậy this làm gì?

+0

Tất cả các phương pháp không tĩnh đều có con trỏ 'this' ẩn. Trong các triển khai C++ điển hình, nó được truyền vào trong khe đối số nguyên đầu tiên. –

+0

Tôi sẽ tránh làm một cái gì đó như thế này - bất kỳ chức năng mà "làm một cái gì đó để một foo" có lẽ nên là một chức năng thành viên/phương pháp của Foo! –

+0

@Wayne Uroda: Không nhất thiết phải. –

Trả lời

24

this đề cập đến đối tượng hiện tại.

Từ khóa this xác định loại con trỏ đặc biệt. Giả sử bạn tạo một đối tượng có tên là x của class Aclass A có hàm thành viên không tĩnh f(). Nếu bạn gọi hàm x.f(), từ khóa this trong phần nội dung của f() sẽ lưu trữ địa chỉ x.

+0

Cảm ơn! Câu trả lời của bạn rất có ý nghĩa với tôi. Đó chính là điều tôi muốn biết. – user2371809

+0

bạn được chào đón :) –

2

đây là một con trỏ đến ngã (đối tượng người gọi này).

Giả sử bạn có đối tượng lớp Xe có tên là phương thức không tĩnh getColor(), lệnh gọi hàm getColor() trả về địa chỉ của ô tô (thể hiện của lớp).

Chức năng thành viên tĩnh không có con trỏ này (vì chúng không liên quan đến một phiên bản).

6

Câu trả lời ngắn gọn là this là từ khóa đặc biệt xác định đối tượng "này" - đối tượng mà bạn hiện đang hoạt động. Câu trả lời dài hơn, phức tạp hơn một chút là:

Khi bạn có class, nó có thể có chức năng thành viên của hai loại: static và không static. Các hàm thành viên không phải là static phải hoạt động trên một cá thể cụ thể của lớp học và chúng cần phải biết ví dụ đó ở đâu. Để giúp họ, ngôn ngữ xác định một biến tiềm ẩn (tức là một biến được khai báo tự động cho bạn khi cần thiết mà không cần phải làm gì) được gọi là this và sẽ tự động được tạo để trỏ đến trường hợp cụ thể của lớp mà chức năng thành viên đang hoạt động.

Hãy xem xét ví dụ đơn giản này:

#include <iostream> 

class A 
{ 
public: 
    A() 
    { 
     std::cout << "A::A: constructed at " << this << std::endl; 
    } 

    void SayHello() 
    { 
     std::cout << "Hi! I am the instance of A at " << this << std::endl; 
    } 
}; 

int main(int, char **) 
{ 
    A a1; 
    A a2; 

    a1.SayHello();   
    a2.SayHello(); 

    return 0; 
} 

Khi bạn biên dịch và chạy này, quan sát rằng giá trị của this là khác nhau giữa a1a2.

2

điều này có nghĩa là đối tượng của Foo mà DoSomething() được gọi.Tôi giải thích nó với ví dụ

void do_something_to_a_foo(Foo *foo_instance){ 
    foo_instance->printFoo(); 
} 

và lớp chúng tôi

class Foo{ 
    string fooName; 
    public: 
     Foo(string fName); 
     void printFoo(); 
     void DoSomething(); 
}; 

Foo::Foo(string fName){ 
    fooName = fName; 
} 
void Foo::printFoo(){ 
     cout<<"the fooName is: "<<fooName<<endl; 
} 
void Foo::DoSomething(){ 
    do_something_to_a_foo(this); 
} 

bây giờ chúng tôi nhanh chóng đối tượng như

Foo fooObject("first); 
f.DoSomething();//it will prints out first 

tương tự bất cứ chuỗi sẽ được chuyển đến Foo constructor sẽ được in trên gọi DoSomething().
Bởi vì ví dụ trong DoSomething() của ví dụ trên "this" có nghĩa là fooObject và trong do_something_to_a_foo() fooObject được truyền theo tham chiếu.

1

Các chức năng thành viên không tĩnh như Foo::DoSomething có thông số tiềm ẩn có giá trị được sử dụng cho this. Tiêu chuẩn quy định điều này trong C++ 11 §5.2.2/4:

Khi một hàm được gọi, mỗi tham số (8.3.5) phải được khởi tạo (8.5, 12.8, 12.1) với đối số tương ứng. [Ghi chú: Các khởi tạo như vậy được sắp xếp theo trình tự không xác định đối với nhau (1.9) - chú thích cuối cùng] Nếu hàm là một hàm thành viên không tĩnh, tham số this của hàm (9.3.2) sẽ được khởi tạo với một con trỏ đến đối tượng của cuộc gọi, được chuyển đổi như thể bằng một chuyển đổi kiểu rõ ràng (5.4).

Do đó, bạn cần đối tượng Foo để gọi DoSomething. Đối tượng đó chỉ đơn giản là trở thành this.

Sự khác biệt duy nhất (và tầm thường) giữa từ khóa this và thông số con trỏ const bình thường được khai báo rõ ràng là bạn không thể lấy địa chỉ this.

3

Chỉ cần một số sự kiện ngẫu nhiên về this để bổ sung cho câu trả lời khác:

class Foo { 
public: 
    Foo * foo() { return this; } 
    const Foo * cfoo() const { return this; /* return foo(); is an error */ } 
}; 

Foo x;  // can call either x.foo() or x.cfoo() 
const Foo y; // can only call x.cfoo() 

Khi đối tượng là const, loại this trở thành một con trỏ đến const.


class Bar { 
    int x; 
    int y; 
public: 
    Bar() : x(1), y(2) {} 
    void bar (int x = 3) { 
     int y = 4; 
     std::cout << "x: " << x << std::endl; 
     std::cout << "this->x: " << this->x << std::endl; 
     std::cout << "y: " << y << std::endl; 
     std::cout << "this->y: " << this->y << std::endl; 
    } 
}; 

Con trỏ this có thể được sử dụng để truy cập vào một thành viên đó đã bị lu mờ bởi một tham số chức năng hoặc một biến địa phương.


template <unsigned V> 
class Foo { 
    unsigned v; 
public: 
    Foo() : v(V) { std::cout << "<" << v << ">" << " this: " << this << std::endl; } 
}; 

class Bar : public Foo<1>, public Foo<2>, public Foo<3> { 
public: 
    Bar() { std::cout << "Bar this: " << this << std::endl; } 
}; 

Nhiều thừa kế sẽ làm cho các bậc cha mẹ khác nhau để có this giá trị khác nhau. Chỉ cha mẹ kế thừa đầu tiên sẽ có cùng giá trị this làm đối tượng dẫn xuất.

0

Nó là một pointer.It địa phương đề cập đến đối tượng hiện hành như đối tượng địa phương

1

Acc. Object Oriented Programming với C++ bởi Balaguruswamy

this là một con trỏ trỏ đến đối tượng mà this hàm được gọi.Ví dụ, hàm gọi A.max() sẽ đặt con trỏ this thành địa chỉ của đối tượng. Con trỏ this hoạt động như một đối số ngầm định cho tất cả các hàm thành viên.

Bạn sẽ tìm thấy một ví dụ tuyệt vời về con trỏ this tại đây. Nó cũng giúp tôi hiểu khái niệm. http://www.learncpp.com/cpp-tutorial/8-8-the-hidden-this-pointer/

0

Con trỏ là đối tượng ngôn ngữ lập trình, có giá trị tham chiếu đến các điểm đến giá trị khác được lưu trữ ở nơi khác trong bộ nhớ máy tính bằng địa chỉ bộ nhớ của nó.

Có thể nói rằng con trỏ là biến chứa địa chỉ bộ nhớ làm giá trị của nó.

+3

Câu trả lời này không giải quyết phần 'này' được đề cập trong câu hỏi của OP. – sjaustirni