用户定义的转换 (C++/CLI)
本节讨论用户定义的转换 (UDC),在一个类型在转换是值类型的引用或实例时或引用类型。
隐式和显式转换
用户定义的转换可能是隐式或显式的。 转换,则不会导致信息丢失,UDC 应是隐式的。 否则应定义显式 UDC。
本机选件类的构造函数还可用于将引用或值类型转换为本机选件类。
有关转换的更多信息,请参见 装箱(C++ 组件扩展) 和 标准转换。
// 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);
}
Output
转换运算符
从转换运算符创建运算符从其他某选件类对象定义选件类的对象。
标准 C++ 转换不从运算符支持;标准 C++ 用构造函数此目的。 但是,在中,在使用 CLR 时,键入 Visual C++ 提供语法对支持从转换运算符。
与其他符合 CLS 的语言若要最好兼容,您可能希望包装特定选件类的每个用户定义的一元求构造函数有相应转换运算符。
从转换运算符:
将定义为静态函数。
可以是隐式 (对于不丢失精度例如短为 int) 的转换或显式的,如果可能,具有精度时丢失。
将返回包含的选件类的对象。
将具有“from”类型作为唯一参数类型。
下面的示例演示一个隐式和显式“转换”,用户定义的转换 (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);
}
Output
转换为运算符
转换为运算符将转换运算符定义为其他对象选件类的对象。 下面的示例演示一个隐式转换,为后,用户定义的转换运算符:
// 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);
}
Output
显式用户定义转换到的转换运算符。在某些方面可能会丢失数据的转换是正确的。 若要调用显式转换对运算符,必须使用转换。
// 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);
}
Output
转换泛型选件类
您可以将泛型选件类为 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) );
}
Output
一个转换的构造函数采用类型并用它来创建对象。 一个转换的构造函数调用时直接初始化;转换不会调用转换构造函数。 默认情况下,构造函数转换为 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);
}
Output
此代码示例,隐式静态转换函数执行操作和一个显式转换构造函数相同。
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);
}
Output