2011-11-23 42 views
16

Giả sử someClass là một lớp được định nghĩa trong C# với một số phương thức int doSomething(void) và để đơn giản, cung cấp một hàm tạo không tham số. Sau đó, trong C#, trường hợp phải được tạo ra trên heap gc:Bối rối: tạo ví dụ của lớp C# trong C++

someClass c;     // legit, but only a null pointer in C# 
// c->doSomething()   // would not even compile. 
c = new someClass();   // now it points to an instance of someclass. 
int i = c->doSomething();  

Bây giờ, nếu someClass được biên dịch vào một số thư viện Net, bạn cũng có thể sử dụng nó trong C++/CLI:

someClass^ cpp_gcpointer = gcnew someClass(); 
int i = cpp_gcpointer->doSomething(); 

Thật dễ dàng! Nifty! Đây là khóa học giả định một tham chiếu đến thư viện .Net đã được thêm vào dự án và một khai báo sử dụng tương ứng đã được thực hiện. Đó là sự hiểu biết của tôi rằng đây là tương đương C++/CLI chính xác của ví dụ C# trước đó (được cô đọng thành một dòng đơn, đây không phải là điểm tôi quan tâm). Chính xác? (Xin lỗi, tôi mới đến chủ đề)

Trong C++, tuy nhiên, cũng

someClass cpp_cauto;    // in C++ declaration implies instantiation 
int i = cpp_cauto.doSomething(); 

là cú pháp hợp lệ. Trong tò mò, tôi đã thử điều này ngày hôm nay. Một đồng nghiệp, nhìn qua vai tôi, sẵn sàng đặt cược nó thậm chí sẽ không biên dịch. Anh ta sẽ thua cược. (Đây vẫn là lớp từ assembly C#). Trên thực tế nó cũng tạo ra kết quả tương tự i làm mã từ các ví dụ trước.

Tiện lợi, quá, nhưng - uhmm - chính xác là gì, những gì được tạo ở đây? Đoán tự nhiên đầu tiên của tôi là đằng sau lưng của tôi, Net tự động tạo ra một thể hiện trên gc heap và cpp_auto là một số loại wrapper cho đối tượng này, hành xử cú pháp giống như một thể hiện của lớp someClass. Nhưng sau đó tôi tìm thấy trang này

http://msdn.microsoft.com/en-us/library/ms379617%28v=vs.80%29.aspx#vs05cplus_topic2

Trang này dường như cho tôi biết, đó (ít nhất, nếu SomeClass là một lớp C++) cpp_auto là thực sự tạo ra trên stack, trong đó, để kiến ​​thức của tôi, sẽ là hành vi tương tự bạn nhận được trong C++ cổ điển. Và một cái gì đó bạn không thể làm trong C# (bạn có thể không, có thể bạn?). Những gì tôi muốn biết: là trường hợp từ hội đồng C# cũng tạo ra trên ngăn xếp? Bạn có thể tạo ra .Net nhị phân trong C++ với các cá thể lớp trên ngăn xếp mà bạn không thể tạo trong C#? Và điều này có thể thậm chí có thể cung cấp cho bạn một sự thuận lợi :-)?

Trân trọng!

Thomas

Trả lời

12

Các link you referenced giải thích điều này một cách chi tiết:

C++/CLI cho phép bạn sử dụng ngăn xếp ngữ nghĩa với các loại tài liệu tham khảo. Điều này có nghĩa là bạn có thể giới thiệu một kiểu tham chiếu bằng cách sử dụng cú pháp dành riêng cho việc phân bổ các đối tượng trên stack. Trình biên dịch sẽ chăm sóc cung cấp cho bạn các ngữ nghĩa mà bạn mong đợi từ C++, và dưới các bìa đáp ứng các yêu cầu của CLR bằng cách phân bổ thực tế đối tượng trên vùng được quản lý.

Về cơ bản, nó vẫn thực hiện một xử lý để loại tài liệu tham khảo trên heap quản lý, nhưng tự động gọi Dispose() trên IDisposable hiện thực khi nó đi ra khỏi phạm vi cho bạn.

Ví dụ đối tượng, tuy nhiên, vẫn được phân bổ hiệu quả qua gcnew (được đặt trên vùng được quản lý) và được thu thập bởi bộ thu gom rác. Điều này cũng được giải thích chi tiết:

Khi d hết phạm vi, phương thức Vứt bỏ sẽ được gọi để cho phép tài nguyên của nó được giải phóng. Một lần nữa, kể từ khi đối tượng thực sự được phân bổ từ vùng heap được quản lý, bộ thu gom rác sẽ xử lý nó trong thời gian riêng của nó.

Về cơ bản, đây là tất cả được xử lý bởi trình biên dịch để làm cho mã trông và hoạt động giống như các lớp cấp phát chuẩn C++, nhưng thực sự chỉ là một trình biên dịch. Mã IL kết quả vẫn đang thực hiện phân bổ heap được quản lý.

+0

Ouch. Vì vậy, tôi tìm thấy câu trả lời mà không nhận ra nó. Cảm ơn bạn đã chỉ cho tôi điều này :-) – Thomas

+0

@Thomas Không sao cả. Đó là một trang lớn - bạn phải biết những gì cần tìm trong đó để tìm các cuộc thảo luận về thủ thuật biên dịch;) –

+0

Cảm ơn bạn một lần nữa, nhưng tốt, bạn thấy đấy, không phải vì nó là một trang lớn. Vấn đề là tôi chỉ hiểu trích dẫn sau khi bạn đã chỉ ra với tôi rằng nó trả lời câu hỏi của tôi. Nhưng có lẽ đây chỉ là người mới bắt đầu vô minh. Và sau đó, tất nhiên, sự thiếu hiểu biết là phúc lạc :-) – Thomas

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