Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Bagian ini membahas konversi yang ditentukan pengguna (UDC) ketika salah satu jenis dalam konversi adalah referensi atau instans jenis nilai atau jenis referensi.
Konversi implisit dan eksplisit
Konversi yang ditentukan pengguna bisa implisit atau eksplisit. UDC harus implisit jika konversi tidak mengakibatkan hilangnya informasi. Jika tidak, UDC eksplisit harus didefinisikan.
Konstruktor kelas asli dapat digunakan untuk mengonversi referensi atau jenis nilai ke kelas asli.
Untuk informasi selengkapnya tentang konversi, lihat Boxing dan Konversi Standar.
// 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);
}
Hasil
in N::N
in N::N
Operator Dari-Konversi
Operator convert-from membuat objek dari kelas di mana operator tersebut didefinisikan, menggunakan objek dari kelas lain.
C++ standar tidak mendukung operator convert-from; C++ standar menggunakan konstruktor untuk tujuan ini. Namun, saat menggunakan jenis CLR, Visual C++ memberikan dukungan sintik untuk memanggil operator convert-from.
Untuk beroperasi dengan baik dengan bahasa yang sesuai dengan CLS lainnya, Anda mungkin ingin membungkus setiap konstruktor unary yang ditentukan pengguna untuk kelas tertentu dengan operator convert-from yang sesuai.
Operator konversi-dari
Harus didefinisikan sebagai fungsi statis.
Dapat berupa implisit (untuk konversi yang tidak kehilangan presisi seperti short-to-int) atau eksplisit, ketika mungkin ada hilangnya presisi.
Mengembalikan objek dari kelas yang memuat.
Harus memiliki tipe "from" sebagai satu-satunya jenis parameter.
Sampel berikut menunjukkan operator konversi implisit dan eksplisit dari, serta operator konversi yang didefinisikan pengguna (UDC).
// 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);
}
Hasil
in operator
in constructor
10
1
Mengonversi ke operator
Operator convert-to mengonversi objek dari kelas di mana operator didefinisikan ke objek lainnya. Sampel berikut menunjukkan operator konversi implisit, yang mengkonversikan ke tipe yang ditentukan pengguna:
// 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);
}
Hasil
10
Operator konversi eksplisit yang ditentukan pengguna cocok untuk konversi yang berpotensi menyebabkan kehilangan data dalam beberapa cara. Untuk memanggil operator convert-to eksplisit, cast harus digunakan.
// 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);
}
Hasil
10.3
10
Untuk mengonversi kelas generik
Anda dapat mengonversi kelas generik ke T.
// 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) );
}
Hasil
True
Konstruktor konversi mengambil tipe dan menggunakannya untuk membuat objek. Konstruktor konversi hanya dipanggil dengan inisialisasi langsung; cast tidak akan memanggil konstruktor konversi. Secara default, mengonversi konstruktor bersifat eksplisit untuk jenis CLR.
// 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);
}
Hasil
5
R
Dalam sampel kode ini, fungsi konversi statis implisit melakukan hal yang sama dengan konstruktor konversi eksplisit.
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);
}
Hasil
13
12
500
2000