2010-12-14 30 views

Trả lời

22

Trong trường hợp này giá trị tại con trỏ được sao chép (mặc dù điều này không nhất thiết phải là trường hợp như trình tối ưu hóa có thể tối ưu hóa nó ra).

int val = *pPtr; 

Trong trường hợp này tuy nhiên không có bản sao sẽ diễn ra:

int& rVal = *pPtr; 

Lý do không có bản sao xảy ra là do một tài liệu tham khảo không phải là một cấu trúc máy cấp mã. Nó là một cấu trúc mức cao hơn và do đó là một cái gì đó trình biên dịch sử dụng nội bộ hơn là tạo ra mã cụ thể cho nó.

Tương tự, rõ ràng, dành cho các tham số chức năng.

+4

Nó không phải là con trỏ được sao chép trong trường hợp đầu tiên. Đó là giá trị nó trỏ đến đó được sao chép. Trong trường hợp thứ hai, con trỏ được sao chép (logic) và giá trị không phải là. –

+0

@Sergey: Các điểm tốt được phát âm rất khó :) – Goz

+2

Tôi đã viết một chương trình thử nghiệm đơn giản để xác minh câu trả lời cho chính mình, hy vọng điều này sẽ giúp một số http://codepad.org/XDqahndf – RishiD

3

Hy vọng nó không: nếu hàm được gọi nhận đối số của nó theo giá trị.

Hơn nữa, đó là hành vi mong đợi của một tài liệu tham khảo:

void inc(int &i) { ++i; } 

int main() 
{ 
    int i = 0; 
    int *j = &i; 
    inc(*j); 
    std::cout << i << std::endl; 
} 

Mã này được dự kiến ​​sẽ in 1inc mất đối số của nó bằng cách tham khảo. Đã có bản sao được thực hiện khi cuộc gọi inc, mã sẽ in 0.

3

Không. Một tham chiếu ít nhiều giống như một con trỏ với ký hiệu khác nhau và hạn chế không có tham chiếu null. Nhưng giống như một con trỏ nó chỉ chứa địa chỉ của một đối tượng.

+2

"Nhưng giống như một con trỏ nó chỉ chứa địa chỉ của một đối tượng." Tham chiếu không có sự tồn tại của riêng nó. Nó chỉ là một bí danh đối tượng mà nó đã được khởi tạo. Vì vậy, nói rằng "nó chứa" địa chỉ sẽ là sai. Tham chiếu chỉ trỏ đến cùng một địa chỉ với đối tượng gốc, nó không chứa địa chỉ đó. –

+0

Tại sao không? Làm thế nào nó có thể trỏ đến đâu đó và không chứa địa chỉ? Nó có chứa nó, chỉ có bạn không thể truy cập vào địa chỉ nó chứa bởi vì nó tự động bị hủy đăng ký bất cứ khi nào bạn truy cập nó. –

+0

@Sergey Tachenov: Trình biên dịch phải tạo ra tiểu thuyết rằng đó là bí danh và có thể giả định nó. Điều này có nghĩa là tùy thuộc vào việc sử dụng, trình biên dịch có thể tạo ra một con trỏ * nội bộ * và tự động dereference nó sử dụng, hoặc trong một số trường hợp nó chỉ có thể tham khảo các đối tượng ban đầu hoàn toàn. Trong hầu hết các trường hợp, nó phải dùng đến con trỏ, nhưng vào cuối ngày, bạn tốt hơn suy nghĩ theo thuật ngữ trừu tượng: tham chiếu là * bí danh * bất kể chúng được triển khai như thế nào. –

6

Trong trường hợp đơn giản, không. Có những trường hợp phức tạp hơn, mặc dù:

void foo(float const& arg); 
int * p = new int(7); 
foo(*p); 

Ở đây, một đối tượng tạm thời được tạo ra, vì kiểu của con trỏ dereferenced (int) không phù hợp với loại hình cơ bản của tham số chức năng (float). Một chuỗi chuyển đổi tồn tại và tạm thời được chuyển đổi có thể bị ràng buộc với arg vì đó là tham chiếu const.

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