【重学 C++06 | C++该不该使用 explicit

2023年 7月 12日 28.0k 0

文章首发

【重学 C++】06 | C++该不该使用 explicit

引言

大家好,我是只讲技术干货的会玩code,今天是【重学C++】的第六讲,在 C++中,explicit关键字作用于类的构造函数或类型转换操作符,以禁止隐式类型转换。今天,我们来聊聊到底该不该使用explicit

explicit的作用

在C++中,默认允许隐式转换,隐式类型转换是指在表达式中自动进行的类型转换,无需显式地指定转换操作。

struct Im {
 Im();
 Im(int);
};

void read_im(const Im&);

int main(int argc, char const *argv[])
{

 Im i1;
 
 Im i2 = Im();
 
 Im i3 = Im(1);
 
 Im i4 = {};
 
 Im i5 = 1;
 
 Im i6 = {1};
 
 read_im({});
 
 read_im(1);
 
 read_im({1});
}


上面的i4i5i6以及后面的read_im的调用都是隐式转换,以i5为例,能够将整数1转换成Im(1)

使用explicit关键字修饰类的构造函数,禁止隐式类型转换后,在进行类型转换时必须显式地指定转换操作。


struct Ex {
 explicit Ex();
 explicit Ex(int);
};

void read_ex(const Ex&);

int main(int argc, char const *argv[]) {

 Ex e1;
 
 Ex e2 = Ex();
 
 Ex e3 = Ex(1);
 
 Ex e4 = 1; // error
 
 read_ex(Ex());
 
 read_ex(Ex(1));
 
 read_ex(1); // error
}


隐式转换问题

隐式转换虽然看起来比较便利,但降低了代码的可读性。并且,在一些情况下,这种转换会导致意外的结果,造成代码错误。

精度丢失

当将一个高精度的数据类型转换为低精度的类型时,可能会导致数据精度的丢失,还是以上面Im数据结构为例。


struct Im {
 Im();
 Im(int);
};

// 将浮点数 1.6 赋值给了 i, 丢失了小数点后的精度
Im i = 1.6;


调用目标函数混乱

假设项目中有这样一段代码


class Book {
 std::string title_;
 std::string author_;
public:
 Book(std::string t, std::string a) :
 title_(t), author_(a) {};
};

void add_to_library(const Book&) {
 std::cout 

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论