类型转换运算符
类型转换运算符是类的一种特殊成员函数,负责将一个类类型的值转换成其他类型
一个类型转换函数必须是类的成员函数,不能有返回类型,形参列表也必须为空,通常是const的。
operator type() const;
class SmallInt
{
public:
SmallInt(int i = 0) :val(i) {}//转换源,为int型。可将算术类型转换成SmallInt类型
//没有限制类型转换,可以是转换成非常量
operator int()const { return val; }//将SmallInt类型转换成int
operator int*()const { return p; }
//显式的类型转换运算符,只能是常量
explicit operator int()const { return val; }
SmallInt operator=(SmallInt si)
{
this->val = si.val;
return *this;
}
private:
int val;
int *p;
};
SmallInt si,si2;
si = 4;//调用的类型转换将4转换成SmallInt,再调用重载赋值运算符
si = si2;//直接调用的重载赋值运算符
cout << si + 3 << endl;//先将si隐式的转换成int,再调用整数的加法
cout << static_cast<int>(si) + 3 << endl;
如果类中包含一个或多个类型转换,则必须确保在类类型和目标类型之间只存在唯一一种转换方式,避免二义性
实参匹配和相同的类型转换
struct B;
struct A
{
A() = default;
A(const B&);//把一个B转换成A,使用的是拷贝构造
};
struct B
{
operator A() const;//也是把B转换成A,使用的是类型转换
};
A f(const A&);
B b;
A a = f(b);//错误,二义性,是调用的f(B::opreator A()),还是f(A::A(const B&))
出现二义性的时候可以显示的指明调用的是那个
A a1 = f(b.opreator A());
A a2 = f(A(b));
定义内置类型时的二义性
struct A
{
//再调用时会发生,不清楚调用的是int还是double
A(int = 0);
A(double);
operator int()const;
operator double()const;
};
重载函数与类型转换构造函数
struct C
{
C(int);
};
struct D
{
D(int);
};
void manip(const C&);
void manip(const D&);
manip(10);//二义性错误 manip(C(10))还是manip(D(10));
manip(C(10));//可通过显示指明调用
函数重载与类型转换
struct E
{
E(double);
};
void manip2(const C&);
void manip2(const E&);
manip2(10);//二义性错误 manip(C(10))还是manip(E(double(10)));
函数匹配和重载运算符
就是再定义重载运算符时和类型转换运算符时的二义性问题
struct Data
{
Data operator+(const Data &da);
Data(int = 0);
operator int()const;
};
Data d1;
int x = d1 + 0;//二义性错误
使用的是内置类型的+,还是operator+
可以把0转换成Data,然后使用Data的+;或者把d1转换成int。如果没定义Data+的话就没有这个二义性。