Udostępnij za pośrednictwem


Śledzenie dojścia do wartości spakowanej

Użycie uchwyt śledzenia, aby odwoływać się do typu wartości zmienił się z zarządzanych rozszerzeń języka C++ do Visual C++.

Bokserskie jest specyfiki typu CLR unified systemu.Typy wartości bezpośrednio zawierać ich stanu, podczas gdy typy odwołań są niejawne parę: nazwana jednostka jest to dojście do obiektu bez nazwy przydzielonych na stercie zarządzanych.Zainicjowanie danych lub przypisanie wartości wpisz do Object, na przykład wymaga, aby typ wartości być umieszczane w ramach sterty CLR-to jest gdzie powstaje obraz boksie to-po raz pierwszy przez przydzielanie pamięci skojarzone, a następnie kopiując stan typ wartości, a następnie zwraca adres ten anonimowy hybrydowy wartości/odwołania.Tak więc, kiedy pisze jeden w języku C#

object o = 1024; // C# implicit boxing

jest o wiele bardziej dzieje niż sygnalizowane przez uproszczenia kodu.Projekt C# powoduje ukrycie złożoności nie tylko jakie operacje odbywają się pod maską, ale także pozyskiwania boksie sam.Zarządzane rozszerzenia języka C++, z drugiej strony, zainteresowanych, to może doprowadzić do fałszywe poczucie efektywności, umieszcza go w twarzy użytkownika poprzez wymóg jawnego instrukcji:

Object *o = __box( 1024 ); // Managed Extensions explicit boxing

Bokserskie jest ukryte w Visual C++:

Object ^o = 1024; // new syntax implicit boxing

__box Służy słowo kluczowe niezbędne usługi w ramach rozszerzeń zarządzanych, który jest nieobecny przez projekt języków, takich jak C# i Visual Basic: zapewnia zarówno słownictwa i śledzenia obsłużyć do bezpośredniej manipulacji spakowanym wystąpieniem na stercie zarządzanych.Rozważmy na przykład następujący program small:

int main() {
   double result = 3.14159;
   __box double * br = __box( result );

   result = 2.7; 
   *br = 2.17;   
   Object * o = br;

   Console::WriteLine( S"result :: {0}", result.ToString() ) ;
   Console::WriteLine( S"result :: {0}", __box(result) ) ;
   Console::WriteLine( S"result :: {0}", br );
}

Podstawowe kodu wygenerowanego dla trzech wywołania WriteLine Pokaż różne koszty dostępu do wartości typu wartość ramkach (dzięki Yves Dolce za wskazanie tych różnic), gdzie wskazane linie Pokaż obciążenie związane z każdym wywołaniem.

// Console::WriteLine( S"result :: {0}", result.ToString() ) ;
ldstr      "result :: {0}"
ldloca.s   result  // ToString overhead
call       instance string  [mscorlib]System.Double::ToString()  // ToString overhead
call       void [mscorlib]System.Console::WriteLine(string, object)

// Console::WriteLine( S"result :: {0}", __box(result) ) ;
Ldstr    " result :: {0}"
ldloc.0
box    [mscorlib]System.Double // box overhead
call    void [mscorlib]System.Console::WriteLine(string, object)


// Console::WriteLine( S"result :: {0}", br );
ldstr    "result :: {0}"
ldloc.0
call     void [mscorlib]System.Console::WriteLine(string, object)

Przechodzi bezpośrednio do typ wartości prostokątnych Console::WriteLine eliminuje zarówno bokserskie oraz potrzebę wywołać ToString(). (Oczywiście ma wcześniejszych bokserskie zainicjować br, więc nie zyskujemy wszystko, chyba że naprawdę umieścić br do pracy.

W nowych składni Obsługa spakowanymi typami wartości jest znacznie bardziej elegancki i zintegrowane w ramach systemu typu przy zachowaniu jego mocy.Na przykład poniżej przedstawiono tłumaczenia wcześniejszego programu small:

int main()
{
   double result = 3.14159;
   double^ br = result;
   result = 2.7;
   *br = 2.17;
   Object^ o = br;
   Console::WriteLine( "result :: {0}", result.ToString() );
   Console::WriteLine( "result :: {0}", result );
   Console::WriteLine( "result :: {0}", br );
}

Zobacz też

Zadania

Porady: jawne żądanie konwersji boxing

Koncepcje

Typy wartości i ich zachowania (C++/CLI)