Aracılığıyla paylaş


Nasıl yapılır: C++/CLI üzerinde safe_cast kullanma

Bu makalede nasıl safe_cast içinde kullanılacağını gösterir C++/CLI uygulamaları.İçinde safe_cast hakkında bilgi için C++/CX, bkz: safe_cast (C++ Bileşen Uzantıları).

Yukarı çevrim

Yukarı çevrim türetilen türden bir dönüştürme için onun temel sınıflardan biri olur.Bu dönüştürme işlemi güvenlidir ve açıkça dönüştürme gösterimi gerektirmez.Aşağıdaki örnek nasıl bir yukarı çevrim ile gerçekleştirileceğini gösterir safe_cast ve onsuz.

// safe_upcast.cpp
// compile with: /clr
using namespace System;
interface class A {
   void Test();
};

ref struct B : public A {
   virtual void Test() {
      Console::WriteLine("in B::Test");
   }

   void Test2() {
      Console::WriteLine("in B::Test2");
   }
};

ref struct C : public B {
   virtual void Test() override {
      Console::WriteLine("in C::Test");
   };
};

int main() {
   C ^ c = gcnew C;

   // implicit upcast
   B ^ b = c;
   b->Test();
   b->Test2();

   // upcast with safe_cast
   b = nullptr;
   b = safe_cast<B^>(c);
   b->Test();
   b->Test2();
}
  

Alta dönüştürme

Alta dönüştürme temel sınıfından türetilmiş bir sınıf için temel sınıfından bir dönüştürme olur.Alta dönüştürme çalışma zamanında ele alınan nesne türetilen sınıf nesnesini gerçekte yalnızca adresleme, güvenli değildir.Aksine static_cast, safe_cast dinamik bir denetimi gerçekleştirir ve atar InvalidCastException dönüştürme başarısız olursa.

// safe_downcast.cpp
// compile with: /clr
using namespace System;

interface class A { void Test(); };

ref struct B : public A {
   virtual void Test() { 
      Console::WriteLine("in B::Test()");
   }

   void Test2() { 
      Console::WriteLine("in B::Test2()");
   }
};

ref struct C : public B {
   virtual void Test() override { 
      Console::WriteLine("in C::Test()");
   }
};

interface class I {};

value struct V : public I {};

int main() {
   A^ a = gcnew C();
   a->Test();
   B^ b = safe_cast<B^>(a);
   b->Test();
   b->Test2();

   V v; 
   I^ i = v;   // i boxes V
   V^ refv = safe_cast<V^>(i); 
   
   Object^ o = gcnew B;
   A^ a2= safe_cast<A^>(o);
}
  

safe_cast ile kullanıcı tanımlı dönüştürme

Sonraki örnek, nasıl kullanacağınızı gösterir safe_cast kullanıcı tanımlı dönüştürmeler çağırmak için.

// safe_cast_udc.cpp
// compile with: /clr
using namespace System;
value struct V;

ref struct R {
   int x;
   R() {
      x = 1;
   }

   R(int argx) {
      x = argx;
   }

   static operator R::V^(R^ r);
};

value struct V {
   int x;
   static operator R^(V& v) {
      Console::WriteLine("in operator R^(V& v)");
      R^ r = gcnew R();
      r->x = v.x;  
      return r;
   }

   V(int argx) {
      x = argx;
   }
};

   R::operator V^(R^ r) {
      Console::WriteLine("in operator V^(R^ r)");
      return gcnew V(r->x);
   }

int main() {
   bool fReturnVal = false;
   V v(2);
   R^ r = safe_cast<R^>(v);   // should invoke UDC
   V^ v2 = safe_cast<V^>(r);   // should invoke UDC
}
  

safe_cast ve kutulama işlemleri

Kutulama

Kutulama derleyici ile eklenen, kullanıcı tanımlı bir dönüştürme tanımlanır.Bu nedenle, kullanabileceğiniz safe_cast bir değer clr Yığınındaki kutu içine almak için.

Aşağıdaki örnek, basit ve kullanıcı tanımlı değer türleri ile paketleme gösterir.A safe_cast , atık toplanan yığında bir değişkene atanabilir, yerel yığında değer türü değişkeni kutuları.

// safe_cast_boxing.cpp
// compile with: /clr
using namespace System;

interface struct I {};

value struct V : public I { 
   int m_x;

   V(int i) : m_x(i) {}
};

int main() {
   // box a value type
   V v(100);
   I^ i = safe_cast<I^>(v);

   int x = 100;
   V^ refv = safe_cast<V^>(v);
   int^ refi = safe_cast<int^>(x);
}

Kutulama kullanıcı tanımlı bir dönüştürme üzerinde önceliğe sahiptir sonraki örnek gösteren bir safe_cast işlem.

// safe_cast_boxing_2.cpp
// compile with: /clr
static bool fRetval = true;

interface struct I {};
value struct V : public I {
   int x;

   V(int argx) {
      x = argx;
   }

   static operator I^(V v) {
      fRetval = false;
      I^ pi = v;
      return pi;
   }
};

ref struct R {
   R() {}
   R(V^ pv) {}
};

int main() {
   V v(10);
   I^ pv = safe_cast<I^>(v);   // boxing will occur, not UDC "operator I^"
}

Kutulama

Kutulama derleyici ile eklenen, kullanıcı tanımlı bir dönüştürme tanımlanır.Bu nedenle, kullanabileceğiniz safe_cast bir değer clr Yığınındaki kaldırmak için.

Kullanıcı tanımlı bir dönüştürme kutulama olduğu halde kutulama aksine, kutulama gerekir açık olması — diğer bir deyişle, onu tarafından gerçekleştirilmesi gereken bir static_cast, c stili artığını, veya safe_cast; kutulama dolaylı olarak gerçekleştirilemez.

// safe_cast_unboxing.cpp
// compile with: /clr
int main() {
   System::Object ^ o = 42;
   int x = safe_cast<int>(o);
}

Aşağıdaki örnek, değer türleri ve temel türler ile kutulama gösterilmiştir.

// safe_cast_unboxing_2.cpp
// compile with: /clr
using namespace System;

interface struct I {};

value struct VI : public I {};

void test1() {
   Object^ o = 5;
   int x = safe_cast<Int32>(o);
}

value struct V {
   int x;
   String^ s;
};

void test2() {
   V localv;
   Object^ o = localv;
   V unboxv = safe_cast<V>(o);
}

void test3() {
   V localv;
   V^ o2 = localv;
   V unboxv2 = safe_cast<V>(o2);
}

void test4() {
   I^ refi = VI();
   VI vi  = safe_cast<VI>(refi);
}

int main() {
   test1();
   test2();
   test3();
   test4();
}

safe_cast ve genel türler

Sonraki örnek, nasıl kullanacağınızı gösterir safe_cast ile genel bir tür alta dönüştürme gerçekleştirmek için.

// safe_cast_generic_types.cpp
// compile with: /clr
interface struct I {};

generic<class T> where T:I
ref struct Base {
   T t;
   void test1() {}
};

generic<class T> where T:I
ref struct Derived:public Base <T> {};

ref struct R:public I {};

typedef Base<R^> GBase_R;
typedef Derived<R^> GDerived_R;

int main() {
   GBase_R^ br = gcnew GDerived_R();
   GDerived_R^ dr = safe_cast<GDerived_R^>(br);
}

Ayrıca bkz.

Başvuru

safe_cast (C++ Bileşen Uzantıları)