Zabalení (C++/CLI a C++/CX)
Převod hodnotových typů na objekty se nazývá boxing a převod objektů na typy hodnot se nazývá unboxing.
Všechny moduly runtime
(Pro tuto funkci jazyka neexistují žádné poznámky, které platí pro všechny moduly runtime.)
prostředí Windows Runtime
C++/CX podporuje zkrácenou syntaxi pro typy hodnot boxingu a rozbalování referenčních typů. Typ hodnoty se zařadí do pole, když je přiřazen k proměnné typu Object
. Proměnná Object
se zruší, když je přiřazena proměnné typu hodnoty a unboxed typ je zadán v závorkách; to znamená, že když je proměnná objektu přetypována na typ hodnoty.
Platform::Object^
object_variable = value_variable;
value_variable = (value_type) object_variable;
Požadavky
Možnost kompilátoru: /ZW
Příklady
Následující příklad kódu polí a rozbalí DateTime
hodnotu. Nejprve příklad získá DateTime
hodnotu, která představuje aktuální datum a čas a přiřadí ji proměnné DateTime
. Potom ho DateTime
přiřadíte k Object
proměnné. Nakonec se pole s hodnotou rozbalí tak, že ji přiřadíte k jiné DateTime
proměnné.
Chcete-li otestovat příklad, vytvořte BlankApplication
projekt, nahraďte metodu BlankPage::OnNavigatedTo()
a potom zadejte zarážky v uzavírací závorce a přiřazení proměnné str1
. Když příklad dosáhne konečné hranaté závorky, prozkoumejte str1
.
void BlankPage::OnNavigatedTo(NavigationEventArgs^ e)
{
using namespace Windows::Globalization::DateTimeFormatting;
Windows::Foundation::DateTime dt, dtAnother;
Platform::Object^ obj1;
Windows::Globalization::Calendar^ c =
ref new Windows::Globalization::Calendar;
c->SetToNow();
dt = c->GetDateTime();
auto dtf = ref new DateTimeFormatter(
YearFormat::Full,
MonthFormat::Numeric,
DayFormat::Default,
DayOfWeekFormat::None);
String^ str1 = dtf->Format(dt);
OutputDebugString(str1->Data());
OutputDebugString(L"\r\n");
// Box the value type and assign to a reference type.
obj1 = dt;
// Unbox the reference type and assign to a value type.
dtAnother = (Windows::Foundation::DateTime) obj1;
// Format the DateTime for display.
String^ str2 = dtf->Format(dtAnother);
OutputDebugString(str2->Data());
}
Další informace naleznete v tématu Boxing (C++/CX).
CLR (Common Language Runtime)
Typy hodnot pole kompilátoru do Object. To je možné kvůli převodu typů hodnot definovaných kompilátorem na Object.
Boxing and unboxing enable value types to be treated as objects. Typy hodnot, včetně typů struktur a předdefinovaných typů, jako je například int, lze převést na typ a z tohoto typu Object.
Další informace naleznete v tématu:
Požadavky
Možnost kompilátoru: /clr
Příklady
Následující ukázka ukazuje, jak funguje implicitní boxování.
// vcmcppv2_explicit_boxing2.cpp
// compile with: /clr
using namespace System;
ref class A {
public:
void func(System::Object^ o){Console::WriteLine("in A");}
};
value class V {};
interface struct IFace {
void func();
};
value class V1 : public IFace {
public:
virtual void func() {
Console::WriteLine("Interface function");
}
};
value struct V2 {
// conversion operator to System::Object
static operator System::Object^(V2 v2) {
Console::WriteLine("operator System::Object^");
return (V2^)v2;
}
};
void func1(System::Object^){Console::WriteLine("in void func1(System::Object^)");}
void func1(V2^){Console::WriteLine("in func1(V2^)");}
void func2(System::ValueType^){Console::WriteLine("in func2(System::ValueType^)");}
void func2(System::Object^){Console::WriteLine("in func2(System::Object^)");}
int main() {
// example 1 simple implicit boxing
Int32^ bi = 1;
Console::WriteLine(bi);
// example 2 calling a member with implicit boxing
Int32 n = 10;
Console::WriteLine("xx = {0}", n.ToString());
// example 3 implicit boxing for function calls
A^ a = gcnew A;
a->func(n);
// example 4 implicit boxing for WriteLine function call
V v;
Console::WriteLine("Class {0} passed using implicit boxing", v);
Console::WriteLine("Class {0} passed with forced boxing", (V^)(v)); // force boxing
// example 5 casting to a base with implicit boxing
V1 v1;
IFace ^ iface = v1;
iface->func();
// example 6 user-defined conversion preferred over implicit boxing for function-call parameter matching
V2 v2;
func1(v2); // user defined conversion from V2 to System::Object preferred over implicit boxing
// Will call void func1(System::Object^);
func2(v2); // OK: Calls "static V2::operator System::Object^(V2 v2)"
func2((V2^)v2); // Using explicit boxing: calls func2(System::ValueType^)
}
1
xx = 10
in A
Class V passed using implicit boxing
Class V passed with forced boxing
Interface function
in func1(V2^)
in func2(System::ValueType^)
in func2(System::ValueType^)