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(); // 对
总的来说,不要提供转换函数,除非真的需要它。
上一篇: 算法(第四版)读书笔记 第一章
推荐阅读
-
《Effective C++》读书笔记 资源管理
-
《Effective C++》读书笔记 被你忽略的关于构造析构赋值
-
Effective C++ 笔记:条款 31 将编译关系降至最低
-
More Effective C++在leveldb中的体现
-
Effective Modern C++ 条款32 对于lambda,使用初始化捕获来把对象移动到闭包
-
Effective Modern C++ 条款23 理解std::move和std::forward
-
Effective Modern C++ 条款37 在所有路径上,让std::thread对象变得不可连接(unjoinable)
-
Effective Modern C++ 条款38 意识到线程句柄的析构函数的不同行为
-
Effective Modern C++ 条款22 当使用Pimpl Idiom时,在实现文件中定义特殊成员函数
-
Effective C++ 笔记:条款 33 避免继承导致的名称遮掩