先看代码:
#include <iostream>
using namespace std;
class A
{
public:
A(int k): m_k(k)
{
}
A(const A&a): m_k(a.m_k)
{
cout << "copy ctor" << endl;
}
private:
int m_k;
};
int main()
{
A a1(1);
A a2 = 1;
return 1;
}
A a1(1); A a2 = 1;这两句代码有啥区别?
A a1(1); 调用A::A(int),这是直接初始化。
重点说说下面的拷贝初始化:
A a2 = 1;语义上相当于 A a2 (A(1)); 即先调用A::A(const A&),再调用A::A(int)。但是编译器会进行优化,略掉A(1)临时变量的构造,直接使用A::A(int)。
这种优化不意味着A::A(const A&)是可有可无的,不信把A::A(const A&)声明成private,然后再编译看看:)。这意味着编译器会对拷贝构造函数的声明(不是实现)进行合法性检查。
事实上,拷贝初始化允许编译器先调用一个用户自定义的转换,然后再调用拷贝构造函数。上面的A::A(int)相当于一个用户自定义转换:从int到A的转换。如果把A::A(int)声明成explicit,照样编译不通过。
另外operator type()也是用户自定义转换的一种,比如:
class B
{
public:
operator A()
{
return A(1);
}
};