2012-10-23 40 views
10

Tôi đã đọc qua việc triển khai Danh sách (và nút của nó) bằng cách sử dụng các lớp và tôi đã tìm thấy một vài điều tôi không hiểu lắm. Dưới đây là đoạn code trong lớp Node mà tôi không hiểu:Kết hợp & và * toán tử

class Node { 
     private: 
     Data data; 
     Node* next; 
     public: 
     Node*& getNext(); 
    }; 

    Node*& Node::getNext() 
    { 
     return this->next; 
    } 

là gì * & chính xác? Tôi không nhận được loại biến nào được trả về bằng phương thức đó.

Tôi nghĩ rằng tôi nhận được nó bây giờ, sau này tôi có những dòng này (bên trong Danh sách lớp):

Node** node = &first; 
node = &(*node)->getNext();  

Liệu đó có nghĩa là tôi đang lưu trữ địa chỉ của tiếp theo trong nút *?

Lưu ý: Câu hỏi thứ hai đã được trả lời trong các nhận xét. Cảm ơn bạn đã trả lời.

+1

Đó là tham chiếu đến con trỏ. –

+1

Bạn nên luôn đặt ra hai câu hỏi khi bạn nghĩ trả về một tham chiếu có thể là một ý tưởng hay: 1) Có phải điều được trả về thực sự thuộc sở hữu của người dùng 'Node' không? 2) Liệu tham chiếu không bao giờ tồn tại đối tượng mà nó đề cập đến? Thường chỉ xem xét trả về một tham chiếu nếu cả hai câu trả lời là có. –

+2

Nó không phải là một nhà điều hành. – Puppy

Trả lời

9

Đó là tham chiếu đến con trỏ. Nó có nghĩa là trả về hàm là Node* là một bí danh cho Node::next.

Ví dụ, nói rằng bạn có:

Node n; 
n.getNext() = NULL; 

này đặt n.next-NULL.

Nếu phương pháp này không trở về bằng cách tham khảo

Node* Node::getNext() //no reference 
{ 
    return this->next; 
} 

cùng mã

Node n; 
n.getNext() = NULL; 

sẽ không sửa đổi n.next - và, trong trường hợp này, nó sẽ để nguyên không khởi biên dịch vì getNext trả về một rvalue tại đây.

Ngoài ra, trở về bằng cách tham khảo:

Node*& x = n.getNext(); 
x = new Node; 

sẽ sửa đổi n.next, như x là một tham chiếu đến n.next.

+0

-1 'n.getNext() = NULL;' cho 'Node * Node :: getNext()' sẽ không biên dịch. bạn không thể gán cho một rvalue. –

+0

@ Cheersandhth.-Alf đúng, điểm tốt, đã mang đi :) –

+0

anh ấy. được. loại bỏ các downvote. –

4
Node*& getNext(); 

Trả lại tham chiếu đến Node*. Tại sao họ chọn trả về tham chiếu không const cho một con trỏ, cho phép giá trị của nó được thay đổi bởi người gọi hàm ... Tôi không biết.

4

Điều đó có nghĩa là bạn sẽ trả lại con trỏ theo tham chiếu. Có nghĩa là ai đó có thể sửa đổi con trỏ thực tế bên trong một nút:

Node anode = /* something... */; 
anode.getNext() = nullptr; 
assert(anode.getNext() == nullptr); // assertion passed! 

Đây không phải là trường hợp bạn sẽ sử dụng.Chỉ cần trả lại con trỏ:

Node* Node::getNext() 
{ 
    return next; 
} 
4

Hãy so sánh

class Node { 
    private: 
    Data data; 
    Node* next; 
    public: 
    Node*& getNext(); 
}; 

Node*& Node::getNext() 
{ 
    return this->next; 
} 

để

class Node { 
    private: 
    Data data; 
    public: 
    Node* next; 
}; 

Những đoạn mã đạt gần giống nhau, nhưng sau này là

  • ngắn hơn,

  • đơn giản hơn, và

  • cho phép truy cập vào các con trỏ next cũng trên một đối tượng const.

Vì vậy, với tất cả những gì không cần thiết phức tạp và hạn chế, chưa kể đến Java-ISMS như Get tiền tố và việc sử dụng các this->, bạn có thể yên tâm rằng các cấu trúc và thậm chí đặt tên mà bạn thấy trong mã mà , có lẽ hầu hết là không có nghĩa là và thậm chí với hiệu ứng bất lợi – như phương pháp GetNext có, hạn chế quyền truy cập.

Chi tiết kỹ thuật: & là C++ nói cho "tham chiếu" và giải thích cơ bản nhất về tham chiếu C++ là nó là một bí danh đối với một số đối tượng. Trong C++ 03 một tham chiếu không thể phân biệt được với đối tượng mà nó đề cập đến. Không có vấn đề gì với phiên bản C++, không có thứ như tham chiếu null trong mã hợp lệ.

Để thực sự tìm hiểu về con trỏ và tham chiếu, bạn nên sử dụng tốt sách giáo khoa C++ và không dựa vào câu trả lời trong diễn đàn mạng.

SO C++ FAQ book list có nhiều đề xuất tốt cho sách giáo khoa.

+0

Tôi sẽ downvote, nhưng sau đó tôi nhận ra trở lại bằng cách tham chiếu cũng phá vỡ đóng gói, vì vậy +1. –

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