时间:2021-05-19
实例如下:
class SmallInt {public: SmallInt(int i = 0): val(i) { if (i < 0 || i > 255) throw std::out_of_range("Bad SmallInt initializer"); } operator int() const { return val; }private: std::size_t val;};转换函数采用如下通用形式:
operator type();
type表示内置类型名、类类型名或由类型别名定义的名字。对任何可作为函数返回类型的类型(除了 void 之外)都可以定义转换函数。一般而言,不允许转换为数组或函数类型,转换为指针类型(数据和函数指针)以及引用类型是可以的。转换函数必须是成员函数,不能指定返回类型,并且形参表必须为空。operator int 返回一个 int 值;如果定义 operator Sales_item,它将返回一个 Sales_item 对象,诸如此类。转换函数一般不应该改变被转换的对象。因此,转换操作符通常应定义为 const 成员。
SmallInt si;
double dval;
si >= dval // si converted to int and then convert todouble
优点:类类型转换可能是实现和使用类的一个好处。通过为 SmallInt 定义到int 的转换,能够更容易实现和使用 SmallInt 类。int 转换使 SmallInt 的用户能够对 SmallInt 对象使用所有算术和关系操作符,而且,用户可以安全编写将 SmallInt 和其他算术类型混合使用的表达式。定义一个转换操作符就能代替定义 48个(或更多)重载操作符,类实现者的工作就简单多了。
缺点:二义性
对 extended_compute 的调用有二义性。可以使用任一转换函数,但每个都必须跟上一个标准转换来获得 long double,因此,没有一个转换比其他的更好,调用具有二义性。
如果两个转换操作符都可用在一个调用中,而且在转换函数之后存在标准转换,则根据该标准转换的类别选择最佳匹配。若无最佳匹配,就会出现二义性。
再比如:
可能存在两个转换操作符,也可能存在两个构造函数可以用来将一个值转换为目标类型。
考虑 manip 函数,它接受一个 SmallInt 类型的实参:
第三个调用具有二义性。没有构造函数完全匹配于 long。使用每一个构造函
数之前都需要对实参进行转换:
1. 标准转换(从 long 到double)后跟 SmallInt(double)。
2. 标准转换(从 long 到int)后跟 SmallInt(int)。
这些转换序列是不能区别的,所以该调用具有二义性。
当两个类定义了相互转换时,很可能存在二义性:
实参 int_val 可以用两种不同方式转换为 SmallInt 对象,编译器可以使
用接受 Integral 对象的构造函数,也可以使用将 Integral 对象转换为
SmallInt 对象的 Integral 转换操作。因为这两个函数没有高下之分,所以这
个调用会出错。
在这种情况下,不能用显式类型转换来解决二义性——显式类型转换本身既可以使用转换操作又可以使用构造函数,相反,需要显式调用转换操作符或构造函数:
compute(int_val.operator SmallInt()); // ok: useconversion operatorcompute(SmallInt(int_val)); // ok: use SmallInt constructor改变构造函数以接受 const Integral 引用:
class SmallInt {public:SmallInt(constIntegral&);};则对compute(int_val) 的调用不再有二义性!原因在于使用 SmallInt构造函数需要将一个引用绑定到 int_val,而使用 Integral 类的转换操作符可以避免这个额外的步骤。这一小小区别足以使我们倾向于使用转换操作符。
显式强制转换消除二义性
class SmallInt {public:// Usually it is unwise to define conversions tomultiplearithmetic typesoperatorint() const { return val; }operatordouble() const { return val; }// ...private:std::size_tval;};void compute(int);void compute(double);void compute(long double);SmallInt si;compute(si); // error: ambiguous
可以利用显式强制转换来消除二义性:
compute(static_cast<int>(si)); // ok: convertand call compute(int)
显式构造函数调用消除二义性
可以用显示构造函数消除二义性:
manip(SmallInt(10)); // ok: call manip(SmallInt)manip(Integral(10)); // ok: call manip(Integral)标准转换优于类类型转换
class LongDouble{public: LongDouble(double ); //…};void calc( int );void calc( LongDouble );double dval;calc( dval ); // which function最佳可行函数是voidcalc(int), 调用此函数的转换为:将实参double类型转换为int类型的,为标准转换;调用voidcalc( LongDouble)函数时,将实参从double转换为LongDouble类型,为类类型转换,因为标准转换优于类类型转换,所以第一个函数为最佳可行函数。
以上这篇有关C++中类类型转换操作符总结(必看篇)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C风格的强制类型转换(TypeCast)很简单,不管什么类型的转换统统是:TYPEb=(TYPE)a。C++风格的类型转换提供了4种类型转换操作符来应对不同场合
类型转换操作符(typeconversionoperator)是一种特殊的类成员函数,它定义将类类型值转变为其他类型值的转换。转换操作符在类定义体内声明,在保留
区别C++中对于类来说,对于其中的成员,用点操作符.来获得,而对于一个指向类对象的指针来说,则用箭头操作符->调用该指针所指向对象的成员。当类定义->重载操作符
C++中虚操作符和其他虚函数的规则一样,操作符可以为虚函数,进行动态绑定,虽然这种情况并不多见。本文以赋值操作符operator=举例。派生类中要重定义基类虚函
前言这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容:1.复制构造函数和重载赋值操作符的定义;2.复制构造函数和重载赋值操作符的调用时机;