练习14.45 编写类型转换运算符将一个Sales_data对象分别转换成string和double,你认为这些运算符的返回值应该是什么?
operator std::string() const { return isbn(); }
operator double() const { return revenue; }
练习14.46 你认为应该为Sale_data应该定义上面两种类型转换运算符吗?应该把它们声明成explicit的吗?为什么?
应该。类型转换应该是用户有意识地进行,显示的类型转换可以避免因为意外带来的不好后果。
练习14.47 说明下面这两个类型转换符的区别。
struct Integral {
operator const int();
operator int() const;
};
第一个是返回类型是常量。
第二个是不修改接受类型转换的对象。
练习14.50 在初始化ex1和ex2的过程中,可能用到哪些类类型的转换序列呢?说明初始化是否正确并解释原因。
struct LongDouble {
LongDouble(double = 0.0);
operator double();
operator float();
};
LongDouble ldobj;
int ex1 = ldobj;
float ex2 = ldobj;
对象的初始化是正确的。
对于ex1定义了多个从LongDouble到 int的转换函数。
对于ex2则有精确匹配的float转换函数。
练习14.51 在调用calc的过程中,可能用到哪些类型转换序列呢?说明最佳可行函数是如何被选出来的。
void calc(int);
void calc(LongDouble);
double dval;
calc(dval); //哪个calc?
转换序列double->int或者double->LongDouble(double(daval))。
最佳可行函数是第一个。
在调用重载函数时,如果需要额外的标准类型转换,则该转换的级别只有当所有可行函数都请求同一个用户定义的类型转换才有用。如果所需的用户定义的类型转换不止一个,则该调用具有二义性。
练习14.52 在下面的加法表达式中分别选用了哪个operator+?列出候选函数、可行函数以及为每个可行函数的实参执行的类型转换。
struct LongDouble {
LongDouble operator+(const SamallInt&);
LongDouble(double = 0.0);
operator double();
operator float();
};
LongDouble operator+(LongDouble &, double);
SmallInt si;
LongDouble ld;
ld = si + ld;
ld = ld + si;
第一个加法:
(a) operator+(int,double)<built-in>
(b) operator+(int, float)<built-in>
第二个加法:
(a) double operator+(int)<built-in>
(b) float operator+(int)<built-in>
练习14.53 假设我们已经定义了如522页的SmallInt,判断下面的加法表达式是否合法。如果合法,使用了哪个加法运算符?如果不合法,应该怎样修改代码使其合法?
SmallInt sl;
double d = sl + 3.14;
不合法,会产生二义性。
(a) operator+(int, doule)<built-in>
(b) operator+(int, int) <built-in>
使用显示转换进行修改。
double d = static_cast<double>(s1) + 3.14;