2010-01-27 98 views
6

Trong C++, con trỏ là một con trỏ tới một địa chỉ bộ nhớ trong đó một biến khác được lưu trữ và trong C# tham chiếu là một số giống nhau. sự khác biệt giữa hai cái đó là gì?Sự khác nhau giữa con trỏ trong C++ và kiểu tham chiếu trong C#

+0

Chỉ cần đọc những gì hay nhất. ;-) http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx – Oliver

+0

Xem thêm http://stackoverflow.com/questions/430112/what- is-the-different-between-ac-sharp-tham chiếu-và-một-con trỏ – nawfal

Trả lời

8

Trong C# loại tham chiếu sẽ tự động thu thập rác khi không còn cần thiết nữa.

0

Sự khác biệt đầu tiên là bạn không thể sử dụng số học con trỏ trên tham chiếu. Nếu không, chúng khá giống nhau.

  • Cả hai điểm/tham chiếu đến một đối tượng thực tế.
  • Cả hai có thể được NULL/null (tức là không trỏ đến một đối tượng hợp lệ)
  • Cả hai có thể được gán một đối tượng mới

khác biệt nữa là các bộ sưu tập rác sẽ chăm sóc của các nguồn lực được phân bổ trong C#. Trong C++, bạn phải tự xóa chúng (hoặc sử dụng một con trỏ thông minh).

Và sau đó, tất nhiên ... bạn không cần phải tham khảo các tham chiếu dereference theo cách thủ công trong C# để truy cập giá trị.

+0

oO Tại sao các downvote? – Christian

+0

Các downvote không phải của tôi, nhưng có một sự khác biệt cơ bản mà bạn bỏ qua: .NET Runtime duy trì như là một * bất biến tuyệt đối * mà không có tham chiếu nào được phép tồn tại ở bất kỳ đâu trong vũ trụ mà nó không biết, bên ngoài trường hợp đặc biệt: tham chiếu có thể được đánh dấu là "ghim" và tham chiếu bên ngoài đối tượng được ghim có thể tồn tại đối với các đối tượng được đánh dấu, nhưng có một số lượng đáng kể ghim tại một thời điểm sẽ có tác động bất lợi đến hiệu suất GC. – supercat

0

C++ là con trỏ mức vật lý, nơi nó lưu trữ giá trị của địa chỉ thực. Tham chiếu C# là một con trỏ ẩn hoặc mờ đục, nơi bạn chỉ biết nó trỏ đến một số đối tượng.

Trong C++ bạn làm việc với con trỏ ở cấp độ vật lý - hoạt động bộ nhớ hoặc sử dụng nó truy cập vào các đối tượng mà nó trỏ đến.

// physical level operation 

// set pointer to specific address 
byte *pPointer = 0x00LB10; 
// increment pointer 
pPointer++; 

// OR 
// dereference operation for classes and structure 
pPointer->MyProperty 

Trong C# bạn chỉ có thể sử dụng tham chiếu (đối tượng kiểu tham chiếu) để truy cập các đối tượng.

MyReference.Property 
1

Các tham chiếu được gọi là C# được thực hiện bởi con trỏ trỏ đến đối tượng thực. Chúng được gọi là xử lý và trong khi xử lý chính nó vẫn cố định trong suốt thời gian cuộc sống của chương trình, con trỏ bên trong thay đổi khi đối tượng được di chuyển trong bộ nhớ bởi bộ thu gom rác trong giai đoạn nén bộ nhớ.

+0

Trong khi các triển khai khác nhau của .NET runtime và garbage-collector sẽ miễn phí để thực hiện các công việc khác nhau, các tham chiếu trong các triển khai chung của .NET với một bộ thu gom stop-the-world thực sự là các con trỏ trực tiếp.Khi GC chạy, mọi tham chiếu đến một đối tượng có thể di chuyển sẽ được truy cập và cập nhật để phản ánh vị trí mới của đối tượng. Mã biên dịch có một siêu dữ liệu đặc biệt được liên kết với nó, với mỗi lệnh, thanh ghi nào giữ các tham chiếu trực tiếp và GC có khả năng cập nhật các con trỏ được lưu trữ trong các thanh ghi đó. – supercat

1

Đó là những con thú khác nhau. Trong C++, boost :: shared_ptr có phần tương tự như C# referenecs, nhưng cũng là một con thú khác biệt (của hai).

Các điểm tham chiếu đến đối tượng sẽ được xử lý bởi bộ thu gom rác. Tương tự xảy ra trong trường hợp shared_ptr. Tuy nhiên, có một sự khác biệt về khái niệm giữa cách C# và boost :: shared_ptr theo dõi vòng đời đối tượng (xem bên dưới). C++ con trỏ có thể trỏ đến bất cứ thứ gì, được phân bổ trên stack (trong trường hợp này, không cần xử lý), tĩnh trên đống, hoặc phân bổ theo cách thủ công, theo yêu cầu, trách nhiệm.

Sự khác biệt giữa các tham chiếu shared_ptr và C#:

shared_ptr là bộ đếm tham chiếu. Nó đếm số lượng bản sao của con trỏ của bạn tồn tại và hủy bỏ đối tượng nếu không có. Điều này không cung cấp giải pháp chống tham chiếu chéo (hoặc tham khảo vòng tròn) khi A trỏ tới điểm B đến A, nhưng cả A và B không còn cần thiết nữa.

C# thỏa thuận thu gom rác với điều đó. C# không tính tham chiếu. Thay vào đó, nó duy trì một danh sách truy cập - những gì có thể được truy cập thông qua tất cả các con trỏ mở mà chúng tôi có. Những gì không thể, được xử lý. Cách tiếp cận này an toàn hơn, nhưng có một số nhược điểm về khả năng dự đoán hiệu suất.

8

Đối với tôi, khái niệm này là giống nhau, hoặc ít nhất là dự định được giống nhau, nhưng việc sử dụng thực tế nhất định, không phải là.

Khi chúng ta nói về con trỏ hoặc tham chiếu, chúng ta đang nói về một khái niệm. Biến này "trỏ tới" hoặc "tham chiếu" của nó tới một thứ khác, một thứ gì đó được lưu trữ ở một nơi khác.

Nếu tôi sử dụng tham chiếu đó, ví dụ bằng cách cập nhật giá trị, tôi thực sự đang cập nhật đối tượng được tham chiếu, đối tượng mà biến trỏ đến. Nếu tôi có một đối tượng được tham chiếu từ hai nơi khác nhau, tôi thực sự cập nhật cùng một thứ từ cả hai nơi.

Vì vậy, khái niệm có thể liên quan đến địa chỉ của bạn trong thế giới thực, chỉ là một cách để đề cập đến điều khác và tham chiếu đó có thể được chia sẻ, giống như nhiều người có địa chỉ của tôi.

Sự khác biệt là nhiều hơn về cách nó đã được sử dụng và những gì được cho phép bởi ngôn ngữ. Lưu ý rằng các chi tiết triển khai của tham chiếu hoặc con trỏ không ẩn trong chính khái niệm đó. Trong C# tiếp tục đúng.

Tham chiếu là tham chiếu và vì vậy, chỉ cần không hợp lý để tính tổng hai tham chiếu hoặc để thêm tham chiếu vào một tham chiếu ... điều đó có nghĩa là gì? Tôi không thể thêm hai địa chỉ nhà riêng (như Phố Baker + Đường nhà) ...

Trong C++ chi tiết triển khai của tham chiếu thực sự là tham chiếu. Bằng cách đó, một con trỏ không chỉ là một con trỏ, nó cũng được sử dụng như một địa chỉ bộ nhớ. Bằng cách đó, ví dụ, bạn có thể thêm vào con trỏ, bởi vì nó thực sự có ý nghĩa để thêm hai địa chỉ bộ nhớ để có được một địa chỉ khác, hoặc để thêm 4 vào một địa chỉ bộ nhớ. Vì vậy, trong C++ một con trỏ dừng lại là một khái niệm trở thành một tên được đặt cho một chi tiết thực hiện thực tế.

Đó là lý do tại sao, trong C#, con trỏ và tham chiếu là những thứ khác nhau. Bởi vì, thông qua ngữ nghĩa ý nghĩa là khá giống nhau, họ muốn phân biệt với khái niệm cũ của C và C++, nơi một con trỏ đã trở thành giống như một địa chỉ bộ nhớ.

Tôi khuyên bạn nên đọc bài viết "References are not addresses" từ Eric Lippert nơi tôi tin rằng anh ấy làm tốt công việc giải thích sự khác biệt.

+2

Bạn hoàn toàn không thể thêm hai con trỏ trong C++. – fredoverflow

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