这个问题似乎有些老生长谈,但是今天做了一下实验,发现坑的地方还挺不少。
直接看例子
class A
{
public:
A(int a):s(a){cout<<"int construct!"<<s<<endl;}
A(char *a){cout<<"char construct"<<endl;}
A(const A& a){s=a.s;cout<<"copy!"<<endl;}
A operator=(const A&a){A b(1);cout<<"operator!"<<endl; return b;}
void show(){cout<<s;}
private:
int s;
char a[10];
char *p;
};
int _tmain(int argc, _TCHAR* argv[])
{
char *p=NULL;
A a(5);
A b = 5;
A d = p;
A c = b;
c = a;
c.show();
}
a(5)会调用构造函数,这一点大家都是明白的
A b = 5;这一句,刚开始我以为会调用拷贝构造函数,结果不是,只调用了构造函数
A d = p;也是一样的道理
A c = b 会调用拷贝构造函数
c = a 会调用operator =
总结一下,其实有两种初始化方式,构造函数初始化和拷贝构造函数初始化,当用=号来初始化一个未初始化的变量时调用的是拷贝构造函数
而用=来进行赋值,也就是说左值已经初始化过了,这时才会调用operator=
这里引出了另外一个问题
假设我把
A(int a):s(a){cout<<"int construct!"<<s<<endl;}
这一句声明为explicit,那么不能通过 b = 5;这种方式来初始化b
这就能解释为什么
vector<int> a(5);
是对的
而
vector<int> a = 5;
是错的
在C++ Primer 13.2的习题中,问到过这个问题,答案中写道
由于vector没有提供公有的拷贝构造函数,所以vector<int> a =5;不成立
这是胡扯。
仔细找一下vector的源码也能发现,vector的构造函数声明都是explicit的。