您的位置:首页 > 编程语言 > C语言/C++

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

2013-07-19 23:13 399 查看
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<int>(mi)); //1

fun(static_cast<double>(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;

}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: