欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

More Effective C++ 笔记——条款5

程序员文章站 2022-07-12 17:52:58
...

条款5:对定制的“类型转换函数”保持警觉

C++提供类在不同类型之间执行隐式转换的操作(条款2笔记提到过)。但在某些场景下,这种转换操作会出现一些问题,比如int16转int8,存在截断的隐患。

类似于C++提供的隐式类型转换,我们自己也可以实现定制化的类型转换,比如将自定义的Rational类型转换为double型,具体可以通过隐式类型转换操作符来实现。

所谓隐式类型转换操作符,实际上就是一个拥有奇怪名称的member function(关键词operator 后面加上一个类型名称)。此函数没有返回值,因为其名称就表明了返回类型。例如:

class Rational {
public:
    ......
    operator double() const;  // 将 Rational 转换为 double
};

// 上述函数会在以下情况被自动调用
Rational r(1, 2);  // r = 1/2
double d = 1 * r;  // r被转换为 double 然后再执行乘法运算

但这种类型转换可能会出现问题,因为此类函数在一些你不想调用它的情况下会被自动调用。

Rational r(1, 2)
cout << r;  // 应该输出"1/2",但实际会输出"1.2"

因为当我们没有写一个 operator <<,编译器会自动调用我们写的转换函数,将Rational转换为double然后输出。虽然这并不会造成很严重的错误,但会导致错误(非预期)和函数调用。
解决方法:可以用一个函数取代隐式转换。
c

lass Rational {
public:
    ......
    double asDouble() const;  // 将 Rational 转换为 double
};

Rational r(1, 2);
cout << r;            // 错,没有定义 operator <<
cout << r.asDouble();  // 对

总的来说,不要提供转换函数,除非真的需要它。