C/C++_log2000_explicit关键字

来源:互联网 发布:网络教育专科怎么报名 编辑:程序博客网 时间:2024/05/21 09:30

explicit关键字的用法和语法用途

背景:QT Creator 默认生成的代码 explicit Dialog(QWidget *parent = 0)中,有这么一个关键字explicit,用来修饰构造函数。以前C++写程序的时候,基本上没有碰到这个关键字,那么这个关键字是做什么用的呢?

权威:

explicit修饰构造函数是用来防止隐式转换的,具体一点就是explicit 是避免构造函数的参数自动转换为类对象的标识符。

网上有人这么解释:

“避免一些无意的潜在错误,很多时候一个不经意的赋值本来是错的,结果没有explicit,赋值对象又可隐式转换为参数这种类型,也就成了一个难以发现的BUG ”

再通俗一点:

“google的c++规范中提到explicit的优点是可以避免不合时宜的类型变换,缺点无。所以google约定所有单参数的构造函数都必须是显示的,只有极少数情况下拷贝构造函数可以不声明称explicit。例如作为其他类的透明包装器的类。
 effective c++中说:被声明为explicit的构造函数通常比其non-explicit兄弟更受欢迎。因为它们禁止编译器执行非预期 (往往也不被期望)的类型转换。除非我有一个好理由允许构造函数被用于隐式类型转换,否则我会把它声明为explicit。我鼓励你遵循相同的政策。”

用一段简单代码来验证一下

#include <iostream>using namespace std;class Test{public:    Test(int a){        data = a;    }    void show(){         cout << "data = " << data << endl;    }    private:         int data;};int main(){    Test t = 2;   // 将一个常量赋给了一个对象    t.show();    return 0;}

程序输出:

Starting /home/~/build-2-1-3-Desktop_Qt_5_8_0_GCC_64bit-Debug/2-1-3...data = 2/home/~/build-2-1-3-Desktop_Qt_5_8_0_GCC_64bit-Debug/2-1-3 exited with code 0

为什么会这样呢?原来C++通过隐式转换,构造了一个临时对象Test(2),将它赋给了t(这里调用了默认的构造函数,而不是重载的“=”,因为这是在对象创建的时候)。那么,如果给构造函数加上关键字 explicit ,构造函数变成了explicit Test(int a),再次编译,编译器就会报错。这时,就只能显式地使用构造函数了Test t = Test(2) 。
报错信息:

/home/~/2-1-3/main.cpp:20: error: conversion from ‘int’ to non-scalar typeTestrequested     Test t = 2;   // 将一个常量赋给了一个对象              ^

问:为什么Java语言可以没有这个关键字?

0 0
原创粉丝点击