Ś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