Kullanıcı Tanımlı Dönüşümler (C++/CLI)

Bu bölümde, dönüştürmedeki türlerden biri bir değer türünün veya başvuru türünün başvurusu veya örneği olduğunda kullanıcı tanımlı dönüştürmeler (UDC) ele alınmaktadır.

Örtük ve açık dönüştürmeler

Kullanıcı tanımlı dönüştürme örtük veya açık olabilir. Dönüştürme, bilgi kaybına neden olmazsa bir UDC örtük olmalıdır. Aksi takdirde açık bir UDC tanımlanmalıdır.

Bir başvuruyu veya değer türünü yerel sınıfa dönüştürmek için yerel sınıfın oluşturucus kullanılabilir.

Dönüştürmeler hakkında daha fazla bilgi için bkz . Kutulama ve Standart Dönüştürmeler.

// mcpp_User_Defined_Conversions.cpp
// compile with: /clr
#include "stdio.h"
ref class R;
class N;

value class V {
   static operator V(R^) {
      return V();
   }
};

ref class R {
public:
   static operator N(R^);
   static operator V(R^) {
      System::Console::WriteLine("in R::operator N");
      return V();
   }
};

class N {
public:
   N(R^) {
      printf("in N::N\n");
   }
};

R::operator N(R^) {
   System::Console::WriteLine("in R::operator N");
   return N(nullptr);
}

int main() {
   // Direct initialization:
   R ^r2;
   N n2(r2);   // direct initialization, calls constructor
   static_cast<N>(r2);   // also direct initialization

   R ^r3;
   // ambiguous V::operator V(R^) and R::operator V(R^)
   // static_cast<V>(r3);
}

Çıkış

in N::N
in N::N

Dönüştürme Kaynağı İşleçleri

Dönüştürme işleçleri, işlecinin başka bir sınıfın nesnesinden tanımlandığı sınıfının bir nesnesini oluşturur.

Standart C++ dönüştürme işleçlerini desteklemez; standard C++ bu amaç için oluşturucuları kullanır. Ancak, CLR türlerini kullanırken, Visual C++ dönüştürme işleçlerini çağırmak için ilgili desteği sağlar.

Diğer CLS uyumlu dillerle iyi bir şekilde birlikte çalışabilmek için, belirli bir sınıf için kullanıcı tanımlı tekli oluşturucuları ilgili dönüştürme işleciyle sarmalamanız gerekebilir.

Dönüştürme işleçleri:

  • Statik fonksiyonlar olarak tanımlanmalıdır.

  • Duyarlık kaybı olabileceğinde örtük (kısa-int gibi duyarlığı kaybetmeyen dönüştürmeler için) veya açık olabilir.

  • Içeren sınıfın bir nesnesini döndürür.

  • Tek parametre türü olarak "from" türüne sahip olmalıdır.

Aşağıdaki örnekte örtük ve açık bir "dönüştürme", kullanıcı tanımlı dönüştürme (UDC) işleci gösterilmektedir.

// clr_udc_convert_from.cpp
// compile with: /clr
value struct MyDouble {
   double d;

   MyDouble(int i) {
      d = static_cast<double>(i);
      System::Console::WriteLine("in constructor");
   }

   // Wrap the constructor with a convert-from operator.
   // implicit UDC because conversion cannot lose precision
   static operator MyDouble (int i) {
      System::Console::WriteLine("in operator");
      // call the constructor
      MyDouble d(i);
      return d;
   }

   // an explicit user-defined conversion operator
   static explicit operator signed short int (MyDouble) {
      return 1;
   }
};

int main() {
   int i = 10;
   MyDouble md = i;
   System::Console::WriteLine(md.d);

   // using explicit user-defined conversion operator requires a cast
   unsigned short int j = static_cast<unsigned short int>(md);
   System::Console::WriteLine(j);
}

Çıkış

in operator
in constructor
10
1

Dönüştürme işleçleri

Dönüştürme işleçleri, işlecin tanımlandığı sınıfın bir nesnesini başka bir nesneye dönüştürür. Aşağıdaki örnekte örtük, dönüştürülen, kullanıcı tanımlı dönüştürme işleci gösterilmektedir:

// clr_udc_convert_to.cpp
// compile with: /clr
using namespace System;
value struct MyInt {
   Int32 i;

   // convert MyInt to String^
   static operator String^ ( MyInt val ) {
      return val.i.ToString();
   }

   MyInt(int _i) : i(_i) {}
};

int main() {
   MyInt mi(10);
   String ^s = mi;
   Console::WriteLine(s);
}

Çıkış

10

Açık kullanıcı tanımlı dönüştürme işleci, verileri bir şekilde kaybetme olasılığı olan dönüştürmeler için uygundur. Açık bir dönüştürme işleci çağırmak için bir atama kullanılmalıdır.

// clr_udc_convert_to_2.cpp
// compile with: /clr
value struct MyDouble {
   double d;
   // convert MyDouble to Int32
   static explicit operator System::Int32 ( MyDouble val ) {
      return (int)val.d;
   }
};

int main() {
   MyDouble d;
   d.d = 10.3;
   System::Console::WriteLine(d.d);
   int i = 0;
   i = static_cast<int>(d);
   System::Console::WriteLine(i);
}

Çıkış

10.3
10

Genel sınıfları dönüştürmek için

Genel bir sınıfı T'ye dönüştürebilirsiniz.

// clr_udc_generics.cpp
// compile with: /clr
generic<class T>
public value struct V {
   T mem;
   static operator T(V v) {
      return v.mem;
   }

   void f(T t) {
      mem = t;
   }
};

int main() {
   V<int> v;
   v.f(42);
   int i = v;
   i += v;
   System::Console::WriteLine(i == (42 * 2) );
}

Çıkış

True

Dönüştüren oluşturucu bir tür alır ve nesne oluşturmak için bunu kullanır. Dönüştüren oluşturucu yalnızca doğrudan başlatma ile çağrılır; dönüştürme oluşturucuları çağırmaz. Varsayılan olarak, oluşturucuların dönüştürülmesi CLR türleri için açıktır.

// clr_udc_converting_constructors.cpp
// compile with: /clr
public ref struct R {
   int m;
   char c;

   R(int i) : m(i) { }
   R(char j) : c(j) { }
};

public value struct V {
   R^ ptr;
   int m;

   V(R^ r) : ptr(r) { }
   V(int i) : m(i) { }
};

int main() {
   R^ r = gcnew R(5);

   System::Console::WriteLine( V(5).m);
   System::Console::WriteLine( V(r).ptr);
}

Çıkış

5
R

Bu kod örneğinde örtük statik dönüştürme işlevi, açık dönüştürme oluşturucuyla aynı şeyi yapar.

public value struct V {
   int m;
   V(int i) : m(i) {}
   static operator V(int i) {
      V v(i*100);
      return v;
   }
};

public ref struct R {
   int m;
   R(int i) : m(i) {}
   static operator R^(int i) {
      return gcnew R(i*100);
   }
};

int main() {
   V v(13);   // explicit
   R^ r = gcnew R(12);   // explicit

   System::Console::WriteLine(v.m);
   System::Console::WriteLine(r->m);

   // explicit ctor can't be called here: not ambiguous
   v = 5;
   r = 20;

   System::Console::WriteLine(v.m);
   System::Console::WriteLine(r->m);
}

Çıktı

13
12
500
2000

Ayrıca bkz.

Sınıflar ve Yapılar