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);
}
Çıktı
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);
}
Çıktı
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);
}
Çıktı
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);
}
Çıktı
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) );
}
Çıktı
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);
}
Çıktı
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