2015-10-05 58 views
9

Tôi hiện đang học C++ từ C++ Primer, và nó giải thích cách tham chiếu là bí danh cho một tên biến khác. Nó cũng giải thích cách con trỏ trỏ đến biến khác. Nó nói rằng sự khác biệt giữa một con trỏ và một tham chiếu là các con trỏ có thể được gán lại và các tham chiếu không thể.Sự khác biệt chức năng giữa một con trỏ const (không phải là con trỏ đến const) và tham chiếu là gì?

Trong ví dụ mã sau, tôi có thể làm gì với con trỏ hoặc tham chiếu mà tôi không thể làm với người khác?

double pi = 3.14; 
double &piRef = pi; 
double *const piPnt = π 

//both of these examples are valid and do the same thing 
piRef = 3.14159; 
*piPnt = 3.14159; 

//however, if I attempt to reassign what the pointer points to, it is illegal. 
//this is the same as with a reference, as a reference can't be reassigned either 
double tau = 6.28; 
piPnt = τ 

Tôi biết sự khác biệt nội bộ của mỗi (chẳng hạn như con trỏ là đối tượng, tham chiếu không phải là). Tôi quan tâm đến cách những khác biệt đó quan trọng với lập trình viên ngoài một cú pháp hơi khác một chút. Do đó, đây không phải là bản sao của câu hỏi this trong đó câu trả lời được chấp nhận chỉ nói về những khác biệt nội bộ.

+0

@juanchopanza Con trỏ trong ví dụ của tôi là một con trỏ const, do đó nó không thể được gán lại. – john01dav

+0

Nhưng bạn có thể sử dụng nhiệm vụ trên tham chiếu. Chỉ cần nhớ nó là một bí danh cho một cái gì đó khác. – juanchopanza

+0

@juanchopanza Tôi có thể gán lại giá trị con trỏ trỏ tới. Ví dụ, cả hai 'piRef = 3.14159' và' * piPnt = 3.14169' sẽ là hợp lệ. Một con trỏ có thể là const mà không trỏ đến một đối tượng const. – john01dav

Trả lời

5

Từ một điểm chức năng của con trỏ xem và tham chiếu thực sự là điều tương tự ... chúng tham chiếu một đối tượng và không phải là bản sao của đối tượng đó.

Sự khác biệt thực sự ngoài việc không thể khôi phục tham chiếu là con trỏ có thể là NULL (tức là nó có thể trỏ đến không có gì) trong khi tham chiếu được giả định luôn tham chiếu đối tượng.

Bạn thực sự có thể kết thúc bằng tham chiếu không tham chiếu đối tượng (ví dụ: chuyển *p tới hàm tham chiếu p là con trỏ rỗng) nhưng đây là "hành vi chưa xác định".

Nói cách gợi ý khác có nhiều "linh hoạt" hơn tài liệu tham khảo và điều này cho phép trình biên dịch bỏ qua

  • Đó là một tài liệu tham khảo có thể thay đổi các đối tượng nó tham khảo
  • Đó là một tài liệu tham khảo có thể không có đối tượng

Và điều này có thể trong một số trường hợp tạo mã nhanh hơn.

"Giá" để thanh toán cho tính linh hoạt bổ sung của việc khôi phục và có NULL s là cú pháp (hơi không hài lòng) gây phiền nhiễu hơn.

+1

Trong trường hợp nào tôi muốn sử dụng một hằng số vô giá trị con trỏ? Nếu nó không có sử dụng, nó có thể cũng không tồn tại - nó chắc chắn không có liên quan sau đó. – john01dav

+0

Hai điều kiện của bạn nói rằng trình biên dịch có thể bỏ qua hai điều mà theo như tôi biết không tồn tại. Một tham chiếu không thể trỏ đến một đối tượng không cũng không thể thay đổi những gì nó đang tham chiếu. – john01dav

+1

@ john01dav: chính xác.Những điều này trong C++ là không thể (một cú pháp biên dịch và được thực thi, cái kia bởi vì nó không được hỗ trợ và không xác định) để trình biên dịch có thể tạo mã tốt hơn mã mà nó sẽ tạo ra nếu chúng có thể. Ví dụ '++ x' được thực hiện nhiều lần trong một hàm trong đó' x' là một 'int &' không cần phải tải lại địa chỉ của số nguyên được tham chiếu, trong khi với '(* p) ++' trong đó 'p' là một con trỏ trình biên dịch cũng phải xem xét rằng 'p' có thể đã thay đổi (cũng có thể vì răng cưa). – 6502

1

Tôi có thể làm gì với con trỏ hoặc tham chiếu mà tôi không thể thực hiện với số khác?

double *const piPnt = π 

Những tuyên bố trên

marks piPnt as a read only variable in memory layout 

Vì vậy, piPnt = &xyz sẽ ném ra một lỗi bây giờ.

Nhưng thay đổi giá trị tại địa chỉ con trỏ trỏ đến vẫn hợp lệ.

Tức là, *piPnt = 56 là tốt.

Con trỏ Const hữu ích trong các hệ thống nhúng cần tham chiếu đến cùng một bộ nhớ (ánh xạ cổng). Đó là ánh xạ một lần và các con trỏ liên tục hữu ích ở đây.

Bây giờ liên quan đến tài liệu tham khảo:

double &piRef = pi; 

Bạn không thể khởi tạo lại một tham chiếu trong C++. Bạn có thể gán giá trị khác nhau cho đối tượng mà nó đề cập đến. Đây là một và cùng một đối tượng cho tham chiếu đó mãi mãi. Và đây là những gì bạn đã làm trong ví dụ của bạn.

piRef = 3.14159; 

Một tài liệu tham khảo không thể thay đổi để đề cập đến một đối tượng khác sau khi khởi tạo. Lưu ý rằng việc khởi tạo tham chiếu được xử lý rất khác với việc gán cho nó. Đối số đi qua (5.2.2) và trả về giá trị hàm (6.6.3) là khởi tạo.

Một số nơi tài liệu tham khảo rất hữu ích:

  1. Pointers không thể trỏ đến là tạm thời, tiêu chuẩn rõ ràng cấm làm việc đó. Tham chiếu có thể liên kết với thời gian.
  2. Một con trỏ có thể là NULL trong khi tham chiếu được giả định luôn tham chiếu một đối tượng. Bạn vẫn có thể trả về null từ một hàm trả về một tham chiếu, trình biên dịch sẽ không phàn nàn về nó, nhưng đó là tự tử.
+0

Bạn dường như đang đề cập đến sự tương đồng giữa một con trỏ const và một tham chiếu và sự khác biệt giữa một con trỏ không const và tham chiếu. Tôi đang tìm sự khác biệt giữa một con trỏ const và một tham chiếu. – john01dav

+0

tương ứng, đã chỉnh sửa ngay bây giờ. – basav

4

Tôi có thể làm gì với con trỏ hoặc tham chiếu mà tôi không thể thực hiện với người khác?

Tài liệu tham khảo cho phép bạn viết constructors nhất định và các nhà khai thác quá tải:

class X 
{ 
    // copy constructor 
    X(const X& a); 

    // move constructor 
    X(X&& a); 

    // copy assignment operator 
    X& operator=(const X& a); 

    // move assignment operator 
    X& operator=(X&& a); 
} 

(. Trên thực tế, điều hành quá tải đã được các trường hợp thúc đẩy sử dụng để giới thiệu tài liệu tham khảo vào C++)

gì thường bị bỏ qua là thực tế là hiện đại C + + phân biệt giữa X& (một tham chiếu đến một lvalue) và X&& (một tham chiếu đến một rvalue), nhưng không có điều như một con trỏ đến một rvalue.

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