装箱(C++ 组件扩展)

Visual C++ 编译器可以将值类型转换为调用 装箱的进程的对象,并转换为的对象值类型调用的处理 取消装箱操作。

所有运行时

(不适用于所有运行时间。) 此语言功能的备注

Windows 运行时

C++/CX 支持将装箱值类型的简短语法,并取消装箱引用类型。如果将对象分配给类型 Object的变量时,值类型进行装箱。Object 变量未装箱,如果将对象分配给变量的值时类型,且装箱的类型括号内指定;也就是说,当对象变量转换为值类型。

    Platform::Object^ object_variable  = value_variable;
    value_variable = (value_type) object_variable;

c53ss7ze.collapse_all(zh-cn,VS.110).gif要求

编译器选项:/ZW

c53ss7ze.collapse_all(zh-cn,VS.110).gif示例

下面的代码示例将和取消装箱 DateTime 值装箱。首先,该示例获取表示当前日期和时间并将其分配给 datetime 的变量的日期时间值。然后 datetime 通过将该包给对象变量。最后,则 pack 的值通过将其取消装箱到另一个 datetime 变量。

若要测试示例,请创建一个 BlankApplication 项目,替换 BlankPage::OnNavigatedTo() 方法,然后指定断点在结束括号和分配给可变 str1。当此示例到达结束括号时,请检查 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());
}

公共语言运行时

Visual C++ 编译器现在对值类型进行装箱到 Object。这是由于存在转换值类型进行的编译器中定义的转换为 Object

装箱和取消装箱值类型将使对象。值类型,包括结构类型和内置类型 (如 int,可以向/从类型 Object转换。

有关更多信息,请参见:

c53ss7ze.collapse_all(zh-cn,VS.110).gif要求

编译器选项:/clr

c53ss7ze.collapse_all(zh-cn,VS.110).gif示例

示例

下面的示例演示隐式装箱的工作方式。

// 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^)
}

Output

  
  
  
  
  
  
  
  
  

请参见

概念

适用于运行时平台的组件扩展