C++中explicit关键字的作用
2016-02-26 22:35
441 查看
转自:/article/7142207.html
要明白它的作用,首先要了解隐式转换:可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换。
例如:
这里Things的构造函数可以只用一个实参完成初始化。所以可以进行一个隐式转换,像下面这样:
这段程序使用一个string类型对象作为实参传给Things的CompareTo函数。
这个函数本来是需要一个tings对象作为实参。
现在编译器使用string nm来构造并初始化一个Things对象,新生成的临时的Things对象被传递给CompareTo函数,并在离开这段函数后被析构。
这种行为的正确与否取决于业务需要。
假如你只是想测试一下a的重量与10的大小之比,这么做也许是方便的。
但是假如在CompareTo函数中还涉及到了要除以初始化为0的height属性,那么这么做可能就是错误的。
需要在构造Things之后更改height属性不为0。
所以要限制这种隐式类型转换。
那么这时候就可以通过将构造函数声明为explicit,来防止隐式类型转换。
explicit关键字只能用于类内部的构造函数声明上,而不能用在类外部的函数定义上。现在Things类像这样:
这时再进行编译,在vs2008上会提示:没有可用于执行该转换的用户定义的转换运算符,或者无法调用该运算符。
这时你仍然可以通过显示使用构造函数完成上面的类型转换:
google的c++规范中提到explicit的优点是可以避免不合时宜的类型变换,缺点无。所以google约定所有单参数的构造函数都必须是显示的,只有极少数情况下拷贝构造函数可以不声明称explicit。例如作为其他类的透明包装器的类。
effective c++中说:被声明为explicit的构造函数通常比其non-explicit兄弟更受欢迎。因为它们禁止编译器执行非预期(往往也不被期望)的类型转换。除非我有一个好理由允许构造函数被用于隐式类型转换,否则我会把它声明为explicit。
explicit
explicit用来防止由构造函数定义的隐式转换。要明白它的作用,首先要了解隐式转换:可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换。
例如:
class Things { public: Things(const std::string&name =""): m_name(name),height(0),weight(10){} int CompareTo(const Things & other); std::string m_name; int height; int weight; };
这里Things的构造函数可以只用一个实参完成初始化。所以可以进行一个隐式转换,像下面这样:
Things a; ................//在这里被初始化并使用。 std::string nm ="book_1"; //由于可以隐式转换,所以可以下面这样使用 int result = a.CompareTo(nm);
这段程序使用一个string类型对象作为实参传给Things的CompareTo函数。
这个函数本来是需要一个tings对象作为实参。
现在编译器使用string nm来构造并初始化一个Things对象,新生成的临时的Things对象被传递给CompareTo函数,并在离开这段函数后被析构。
这种行为的正确与否取决于业务需要。
假如你只是想测试一下a的重量与10的大小之比,这么做也许是方便的。
但是假如在CompareTo函数中还涉及到了要除以初始化为0的height属性,那么这么做可能就是错误的。
需要在构造Things之后更改height属性不为0。
所以要限制这种隐式类型转换。
那么这时候就可以通过将构造函数声明为explicit,来防止隐式类型转换。
explicit关键字只能用于类内部的构造函数声明上,而不能用在类外部的函数定义上。现在Things类像这样:
class Things { public: explicit Things(const std::string&name =""): m_name(name),height(0),weight(0){} int CompareTo(const Things & other); std::string m_name; int height; int weight; };
这时再进行编译,在vs2008上会提示:没有可用于执行该转换的用户定义的转换运算符,或者无法调用该运算符。
这时你仍然可以通过显示使用构造函数完成上面的类型转换:
Things a; ................//在这里被初始化并使用。 std::string nm ="book_1"; //显示使用构造函数 int result = a.CompareTo(Things(nm));
google的c++规范中提到explicit的优点是可以避免不合时宜的类型变换,缺点无。所以google约定所有单参数的构造函数都必须是显示的,只有极少数情况下拷贝构造函数可以不声明称explicit。例如作为其他类的透明包装器的类。
effective c++中说:被声明为explicit的构造函数通常比其non-explicit兄弟更受欢迎。因为它们禁止编译器执行非预期(往往也不被期望)的类型转换。除非我有一个好理由允许构造函数被用于隐式类型转换,否则我会把它声明为explicit。
相关文章推荐
- C++栈的初始化,入栈,出栈,获取栈顶元素等操作
- C 和 C++ 混合编程
- C++: string 中find函数的用法以及string::npos的含义
- C语言宏定义和宏定义函数
- C++实现普通队列,循环队列的基本操作(初始化,入队,出队,获取队列首元素等)
- 1065. A+B and C (64bit) (20)
- 线性表—顺序存储(C语言)
- C\C++中内存分几个区
- 数字图像处理-编程实现染色体计数 C语言实现
- C语言学习笔记7-字符串
- C++中的浅拷贝和深拷贝
- C语言学习笔记6-数组
- 【C/C++学院】0901-设计模式的汇总演练
- 本科教育忽略的黄金C++<7> 无序容器
- 1064. Complete Binary Search Tree (30)
- UVa 202, Repeating Decimals
- 最基本的‘*’号图形打印---菱形
- UVa 232, Crossword Answers
- c语言:英尺和米之间的转化
- C语言学习笔记5-程序结构