class Date
{
private:
int year;
public:
Date(int _year=1)
{
year = _year;
}
};
int main()
{
Date d(1);//构造函数
Date d = 1;//构造函数+拷贝构造函数
}
对于一个类,如果是只有单参数,并且单参数的构造函数,那么如果直接Date d=1;就会发生隐式类型的转换。1首先会去构造一个Date的对象,再调用拷贝构造函数,把这个临时对象赋值给d。1这时候就已经不是1了。
创建一个临时对象,把这个临时对象再拷贝构造给对应的对象。因为他们属于不同的栈帧,不创建临时变量就会被销毁,无法返回。
但是某些情况下编译器会发生优化:
但是编译器发生之后,不会去创建临时变量了,会在形成临时变量之前就返回这个对象给另外的一个栈帧中的对象。
这种函数调用return之后直接赋给对象的
class Date
{
private:
int year;
public:
Date(int _year=1)
{
year = _year;
}
};
Date f(Date u)
{
Date v(u);
Date w = v;
return w;
}
int main()
{
Date x;
Date y = f(x);//一次构造,四次拷贝构造
Date yy = f(f(x));//一次构造 七次拷贝构造
}
首先把x传给f();x拷贝构造一次,传递给f(),作为参数u;之后u再去拷贝构造v,拷贝构造两次;之后w=v这一步,也是拷贝构造三次,但是此时就没有构造;最后return的时候返回w给y,拷贝构造四次。
对于yy,第四步不会创建临时变量,会直接将对象给f。这里发生了优化。但是也是第四次拷贝构造。接下来同理,发生5,6,7次拷贝构造。
但是有的编译器会继续优化:u拷贝构造v,v拷贝构造w。不如直接用u来返回。因此中间的这一步就会被省去。
所以有可能是这样子的
Date y = f(x);//一次构造,三次拷贝构造
Date yy = f(f(x));//一次构造 五次拷贝构造