从Qt谈到C++(一):关键字explicit与隐式类型转换
提出疑问
当我们新建了一个Qt的widgets应用工程时。会自动生成一个框架,包含了几个文件。其中有个mainwindow.h的头文件。就是你要操纵的UI主界面了。我们看看其中的一段代码:
class MainWindow : public QMainWindow
{
Q_OBJECT//一个宏,暂不考虑
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
这段代码定义了一个新的类MainWindow,继承自QMainWindow。我们可以看到在它的构造函数里,前面有一个关键字 explicit 。相信大家都对没有这个关键字的构造函数不陌生。那么这个 explicit 是起到什么作用的呢?
explicit研究
类型转换
double a = 12.34;
int b = (int)a;
我们都知道这时b的值是12. 在变量前面加括号包裹的类型,就能实现显式的类型转换。这种叫做强制类型转换。顺便值得一提的是,C++中还支持这种强制类型转换的例子:
double a = 12.34;
int b = int(a);
除此之外,还有一种转换叫做 隐式类型转换。
double a = 12.34;
int b = a;
同样的,b的值也是12.虽然没有显式的转换类型,但是编译器会帮你自动转换。同样的,不仅是基本数据类型,自己定义的类和对象之间也存在这种转换关系。
隐式转换的场景
等于号与构造函数
class A
{
public:
A(int i)
{
a = i;
}
int getValue()
{
return a;
};
private:
int a;
};
A a;
a = 10;
之所以类A的对象可以直接使用整型通过等于号来初始化,是因为这一语句调用了默认的单参数构造函数,这种构造函数又称
类型转换构造函数。其效果等价于A temp(10); a(temp);
注意当你使用A a = 10;时并不会产生中间的临时对象。而是直接把10作为参数传递给类型转换构造函数。
A a = "123";
因为没有参数为字符串的单参数构造函数。知道了这个,你修改一下就能通过了。
class A
{
public:
A(int i)
{
a = i;
}
A(char * c)
{
a=c[0];
}
int getValue()
{
return a;
};
private:
int a;
};
函数调用
void print(A a)
{
cout<<a.getValue();
};
在main函数中:
void main()
{
print(10);
}
这样是可以编译运行的。虽然我们并没有创建一个类A的对象来传给print 函数。但是编译器默认会调用类A的单参数构造函数,创建出一个类A的对象出来。
加上explicit
public:
explicit A(int i)
{
a=i;
}
这样就能避免隐式的类型转换了,当你误写成单引号的时候,就会报错。这样就只允许显示的调用单参数构造函数了。如 A a(10); A b(“123”);
print(A(10));
当然了,是否应该禁止隐式转换是没有定论的,没有一种放之四海皆准的标准,具体看你的情景需要了。
一般而言,显示调用构造器,能避免一些麻烦,让程序员手动来管理。很多人说C++难,因为很多东西对于程序员来说不是透明的,比如内存释放什么的,这个显式调用也是需要程序员自己动手的。然而我感觉这正是C++的魅力所在,C++给了程序员几乎等同于上帝的权力,所有一切都能自己掌控,还比如运算符重载的权力,甚至像Qt这样可以自定义slot和signal关键字(其实是宏),这在其他高级语言里是不可想象的。当然了,语言这东西,是仁者见仁智者见智的。没必要争论优劣。我一直认为的是:没有最优秀的语言,只有最合适的语言。编程语言本身没有优劣之分,但是不同程序员对于不同语言确有好恶之别。
顺便一提
explicit关键字只用在类内部的声明中。在外部的实现部分不需要使用。
#include<iostream>
using namespace std;
class A
{
public:
explicit A(int i);
A(char * c)
{
a=c[0];
}
int getValue()
{
return a;
};
private:
int a;
};
A::A(int i)//无需再指明explicit
{
a=i;
}
void print(A a)
{
cout<<a.getValue();
};
void main()
{
print(A(10));
}
REFERENCE:https://blog.csdn.net/guodongxiaren/article/details/24455653