- 是用来干什么的?
- 一个参数的构造函数 或 除了第一个参数外其余参数都有默认值的构造函数 这两种构造函数和其他构造函数有什么不同?什么情况下不同点会显现出来?
- 什么是隐式转换、显式转换?类的隐式转换?
隐式转换
说白了就是在转换时不给系统提示具体的显示模型,让其自动转换,但是要记住一条编译器一般只支持自下而上的类型转换,例如int 转 float
int a =4; float b= 5.56;
b =a; //这个就是隐式转换,默认的把int a 类型的 转换为float的类型.
显式转换:
int a =4; float b= 5.56;
float c =(float)a;//把int类型的a,强制转换为float类型的。
explicit
防止类之间不应该的隐式转换(通过构造函数)。但是仍可以进行显示类型转换(explicit type conversions)
声明为explicit的构造函数不能在隐式转换中使用。
只含有一个没有默认值的参数的构造函数的作用
- 构造
- 是个默认且隐含的类型转换操作符。
所以, 有时候在我们写下如 AAA = XXX, 这样的代码, 且恰好XXX的类型正好是AAA单参数构造器的参数类型, 这时候编译器就自动调用这个构造器, 创建一个AAA的对象。
这样看起来好象很酷, 很方便。 但在某些情况下, 却违背了程序员的本意。 这时候就要在这个构造器前面加上explicit修饰, 指定这个构造器只能被明确的调用/使用, 不能作为类型转换操作符被隐含的使用。
解析:explicit构造函数是用来防止隐式转换的。请看下面的代码:
#include <iostream>
using namespace std;
class Test1
{
public :
Test1(int num):n(num){}
private:
int n;
};
class Test2
{
public :
explicit Test2(int num):n(num){}
private:
int n;
};
int main()
{
Test1 t1 = 12; //因为是默认构造函数是单参,所以构造+隐式类型转换。
Test2 t2(13); //普通的类实例化
Test2 t3 = 14; //Test2的构造函数用了explicit关键字,不能隐式转换!
return 0;
}
编译时,会指出 t3那一行error:无法从“int”转换为“Test2”。而t1却编译通过。注释掉t3那行,调试时,t1已被赋值成功。
注意:当类的声明和定义分别在两个文件中时,explicit只能写在在声明中,不能写在定义中。