C++语法基础--转换操作符,重载确定

浅浅的花香味﹌ 2021-12-21 06:57 468阅读 0赞

*1.转换操作符
\
将类类型值转变为其他类型值的转换。
*转换操作符在类定义体内声明,在保留字operator之后跟着转换的目标类型, operator type();
*转换函数必须是成员函数,不能指定返回类型(但必须显示返回一个指定类型的值),并且形参表必须为空
*只要存在转换,编译器将在可以使用内置转换的地方自动调用它。
Example:
class MyInt
{
public:
MyInt(int i):x(i){}
operator int(){return x;}
private:
size_t x;
};

int main()
{
MyInt mi(1);
cout<<mi+1<<endl;//2,MyInt并没有重载operator+(),但还是输出了正确的结果
return 0;
}

2.只能应用一次类类型转换(既,转换不具有传递性)
Example:
class MyInt
{
public:
MyInt(int i):x(i){}
operator int(){return x;}
private:
size_t x;
};

class Iterger
{
public:
Iterger(int i):y(i){}
operator MyInt(){return y;}
private:
size_t y;

};

int main()
{

Iterger itg(1);
MyInt mi=itg;//ok ,itg先转换为MyInt,然后复制给mi
cout<<mi+1<<endl;//2
cout<<itg+1;//error,itg先转换为MyInt,但不会再继续转为int;

return 0;
}

3.实参匹配和类型转换
(1)实参匹配和多个转换操作符
*如果两个转换操作符都可以在一个调用中,而且在转换函数之后存在标准转换,则根据该标准转换的类别选择最佳匹配**

Example:

**class MyInt
{
public:
MyInt(int i):x(i){}
MyInt(double i):x(i){}
operator int(){return x;}
operator double(){return x;}
private:
size_t x;
};

void ifun(int x)
{
cout<<x<<endl;
}

void dfun(double x)
{
cout<<x<<endl;
}

void ldfun(long double x)
{
cout<<x<<endl;
}

int main()
{
MyInt mi(1);
ifun(mi); //ok, operator int()
dfun(mi); //ok,operator double()
ldfun(mi); //error,存在二义性
}

Tips:避免二义性的最好方法是,保证最多只有一种途径将一个类型转换为另一个类型**

4.重载确定和类的实参

*\在需要转换函数的实参时,编译器自动应用类的转换操作符或构造函数
*函数重载确定由三步骤组成
(1)确定候选函数函数集合(被调用函数同名的函数)
(2)选择可行的函数(形参数目和类型与函数调用中的实参相匹配的候选函数,如有转换操作,还需确定哪个转换操作来匹配每个形参)
(3)选择最佳匹配的函数

*多个转换和重载容易出现二义性(如果可以使用不同转换操作,编译器则认为这两个转换是一样好的匹配)**

Example:

**class MyInt
{
public:
MyInt(int i):x(i){}
MyInt(double i):x(i){}
operator int(){return x;}
operator double(){return x;}
private:
size_t x;
};

void fun(int x)
{
cout<<x<<endl;
}

void fun(double x)
{
cout<<x<<endl;
}

void ldfun(long double x)
{
cout<<x<<endl;
}

int main()
{
MyInt mi(1);
fun(mi); //error,call of overloaded ‘fun(MyInt&)’ is ambiguous
fun(mi); //error,call of overloaded ‘fun(MyInt&)’ is ambiguous
ldfun(mi); //error,conversion from ‘MyInt’ to ‘long double’ is ambiguous
}

Tips:
解决方法:显式强制转换以消除二义性
int main()
{
MyInt mi(1);
fun(static_cast(mi)); //1
fun(static_cast(mi)); //1

}

5.标准转换和构造函数
*多个转换构造函数的重载确定
class MyInt
{
public:
MyInt(int i):x(i){}
operator int(){return x;}
private:
size_t x;
};

class Interger
{
public:
Interger(int i):x(i){}
operator int(){return x;}
private:
size_t x;
};

void fun(MyInt x)
{
cout<<x<<endl;
}

void fun(Interger x)
{
cout<<x<<endl;
}

int main()
{
fun(1);//Error,call of overloaded ‘fun(int)’ is ambiguous

return 0;
}

解析:
fun(1)存在二义性是因为MyInt,Iterger的构造函数都接受int型的参数,编译器无法确定调用哪个构造函数转换来匹配void fun(MyInt x),void fun(Interger x)

解决方法:显式调用构造函数
int main()
{
fun(MyInt(1));//1
fun(Interger(2));//2

return 0;
}**

发表评论

表情:
评论列表 (有 0 条评论,468人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C++操作符重载

    又看了一遍操作符的东西,感觉之前对操作符的理解还停留在很浅的认知上(仅仅会用哈哈),所以做一下笔记来加深一下印象。 文章目录 一、为什么会有操作符重载

    相关 C++中操作符重载

    一、操作符重载属于什么? 在本文开始阐述之前,首先明确,操作符重载是一个具有特殊名的“ 函数 ”。 既然作为函数,那么,就具有函数的特性,一是形参表,二是返回值。 关键字