让我们先看一段代码,有没有发现什么神奇的地方:
class A {
public:
A(int i) : i(i) {}
private:
int i;
};
A a = 5;
小黄鸭小c:一个a类的对象居然可以用一个整数进行赋值。
小黄鸭小a:有可能是没有进行赋值,只是看起来是一个赋值语句,实际上可能只是通过有参构造实例化了a。
那我们来看一下是不是进行了赋值,要怎么看呢?看代码吧
class A {
public:
A(int i) : i(i) {
cout << "A(i)" << endl;
}
A(const A &a) {
cout << "A(A&)" << endl;
}
A& operator=(const A &a) {
cout << "a&=" << endl;
return *this;
}
private:
int i;
};
int main() {
A a = 5;
return 0;
}
/* 输出
A(i)
*/
现实摆在眼前,一些有经验的小鸭子都傻眼了,它们曾经以为,这里是先将整数5,通过有参构造生成一个临时对象,再将此临时对象通过拷贝构造/移动构造实例化出来a对象。
我们再来看一个东西
class A {
public:
explicit A(int i) : i(i) {}
private:
int i;
};
int main() {
A a = 5;
return 0;
}
这时候发现我们报错了
error: no viable conversion from 'int' to 'A'
这是因为其实语句A a = 5实际上是编译器隐式帮我们调用了A(i)这个有参构造,但是加上了explicit关键字之后就需要显式调用有参构造才可以。