2011-11-23 17 views
16

Założenie, że someClass jest klasą zdefiniowaną w C# z pewną metodą int doSomething(void), a dla uproszczenia, dostarczając konstruktora bez żadnych argumentów. Następnie, w C#, instancje mają być tworzone na stercie GCConfused: tworzenie instancji klasy C# w 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();  

Teraz, jeśli someClass jest kompilowany do jakiejś biblioteki .NET, można również użyć go w C++/CLI:

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

To proste! Sprytny! Jest to oczywiście zakładając, że do projektu dodano odniesienie do biblioteki .Net i dokonano odpowiedniej deklaracji użycia.

Rozumiem, że jest to dokładny odpowiednik C++/CLI poprzedniego przykładu C# (skondensowany do pojedynczej linii, nie jest to rzecz, którą mnie interesuje). Poprawny? (Przepraszam, jestem nowy w temacie)

W C++, jednak również

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

jest prawidłowa składnia. Z ciekawości próbowałem tego dzisiaj. Kolega, patrząc przez ramię, był skłonny się założyć, że nie skompiluje się. Straciłby zakład. (To jest nadal klasa z zestawu C#). W rzeczywistości daje to ten sam wynik, co i jako kod z poprzednich przykładów.

Nifty też, ale - uhmm - co to dokładnie jest, co tu powstaje? Moje pierwsze dzikie przypuszczenie było takie, że za moimi plecami .Net dynamicznie tworzy instancję na stertę Gc, a cpp_auto to jakieś opakowanie dla tego obiektu, zachowujące się jak instancja klasy someClass. Ale potem znalazłem tę stronę

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

Ta strona wydaje się mi powiedzieć, że (przynajmniej, jeśli SomeClass były C++ klasa) cpp_auto jest rzeczywiście tworzone na stosie, co do mojej wiedzy, byłoby takie samo zachowanie, jakie można uzyskać w klasycznym C++. I coś, czego nie możesz zrobić w języku C# (nie możesz, prawda?). Co chciałbym wiedzieć: czy instancja z zestawu C# również została utworzona na stosie? Czy możesz tworzyć pliki binarne .Net w C++ z instancjami klasy na stosie, których nie możesz utworzyć w C#? Czy to może nawet dać ci zysk :-)?

poważaniem,

Thomas

Odpowiedz

12

link you referenced wyjaśnia to w szczegółach:

C++/CLI pozwala zatrudniać semantyki stos z typami referencyjnymi. Oznacza to, że możesz wprowadzić typ referencyjny, używając składni zarezerwowanej do przydzielania obiektów na stosie. Kompilator zadba o zapewnienie semantyki, której można się spodziewać po C++, a pod pokrywami spełni wymagania CLR poprzez rzeczywiste przydzielenie obiektu do sterowanej sterty.

Zasadniczo, to jeszcze czyni uchwyt do typu odniesienia na zarządzanej stercie, ale automatycznie wywołuje Dispose() na IDisposable implementacje kiedy wykracza poza zakres dla ciebie.

Instancja obiektu jest jednak nadal skutecznie przydzielana przez gcnew (umieszczona na sterowanej stercie) i gromadzona przez garbage collector. Zostało to również szczegółowo wyjaśnione:

Po wyjściu d z zakresu jego metoda Dispose zostanie wywołana, aby umożliwić zwolnienie zasobów. Ponownie, ponieważ obiekt jest faktycznie przydzielany z zarządzanej sterty, śmieciarz zadba o uwolnienie go w swoim czasie.

Zasadniczo to wszystko jest obsługiwane przez kompilator, aby kod wyglądał i działał jak standardowe klasy przydzielone do stosów w C++, ale jest to po prostu sztuczka kompilatora. Wynikowy kod IL nadal wykonuje przydzielone sterty sterty.

+0

Ouch. Więc znalazłem odpowiedź, nie rozpoznając jej. Dzięki za wskazanie mi tego :-) – Thomas

+0

@Thomas Bez problemu. Jest to duża strona - musisz wiedzieć, czego szukać, aby znaleźć dyskusję na temat sztuczki kompilatora;) –

+0

Jeszcze raz dziękuję, ale cóż, widzisz, to nie dlatego, że jest to duża strona. Chodzi o to, że rozumiem cytat dopiero po tym, jak mi wskazałeś, że odpowiada na moje pytanie. Ale może to tylko ignorancja początkujących. I oczywiście ignorancja jest rozkoszą :-) – Thomas

Powiązane problemy