在C#中,语义不是关于重载
operator =
(这是不允许的),而是提供从任意类型到类型A的转换运算符,或者从类型A到任意类型的转换运算符。
这意味着以下代码(加上A到类型转换):
class A {
public static implicit operator A(string s) {
return new A();
}
public static implicit operator A(double d) {
return new A();
}
public static implicit operator string(A a) {
return string.Empty;
}
public static implicit operator double(A a) {
return 0.0;
}
static void Main(string[] args) {
A a = "hello";
A b = 5.0;
a = "World";
a = 3.14;
double d = a ;
string s = a ;
}
}
适用于赋值操作,无论是简单的赋值(如C和D行)还是在声明中进行的赋值(如A和B行)。E和F行演示了如何将用户类型转换为其他类型。
如何在C++中实现?
在C++中,A和B行是对象构造,将调用相关的构造函数。
C和D行是赋值,将调用相关的赋值运算符。
因此,提供给您的C#代码的C++代码必须为字符串和双精度浮点数提供构造函数和赋值操作,如下所示:
class A
{
public:
A(const std::string & s) { }
A(double d) { }
A & operator = (const std::string & s) { ; return *this ; }
A & operator = (double d) { ; return *this ; }
} ;
这样,你就可以拥有
void main()
{
A a0 = "Hello" ;
A a1("Hello") ;
A a2 = 5.0 ;
A a3(5.0) ;
a0 = "Hello World" ;
a0 = 3.14 ;
}
C++中的强制类型转换运算符怎么样?
C++中的强制类型转换运算符与以下C#转换运算符类似:
class A
{
static public operator string(A a) { }
static public operator double(A a) { }
}
在C++中,强制类型转换运算符是这样写的:
class A
{
public:
operator std::string() { }
operator double() { }
} ;
void main()
{
A a ;
std::string s ;
double d ;
s = a ;
d = a ;
}
为什么C++这么复杂?
在C#中,可以从类类型转换/转换运算符到任何类型,或从任何类型转换到类类型。
在C++中,对于转换,必须选择一种或多种方式,即:构造函数、赋值运算符或强制类型转换运算符,因为在C++中,您对类型和操作有精细的控制,因此必须使用该精细的API。
构造意味着对象不存在,因此构造它到某个默认值然后将其分配给另一个值没有意义(这可能会影响速度)。在C#中,引用/值类型在分配之前为null/清零,因此这不是问题。
赋值意味着对象已经存在,因此可以重用相同的内部来容纳新值。在C#中,原始引用对象被丢弃,并创建另一个对象(如果创建成本高,则需要支付该费用)
至于强制类型转换,在当前情况下用于将现有类转换为另一个您无法控制的类:您无权扩展std::string以适应您的类的构造函数,并且无法向内置类型(如double)添加构造函数。