三种用法
我们知道,类、struct结构体的复制构造函数在三种情况下会被调用,分别是:
1、创建对象a时,使用对象b去初始化对象a 2、函数fun( )的形参是对象时,传递参数时,复制构造函数会被调用 3、函数的返回值是对象时,返回结果时,复制构造函数会被调用
接下来依次看一下这三种情况。
首先是类的定义
class node {
public:
int x, y;
node () {}
node (int _x, int _y) : x(_x), y(_y) {}
node (const node& temp) {
x = temp.x;
y = temp.y;
printf("复制构造函数被调用\n");
}
};
1、创建对象a时,使用别的对象b去初始化a
int main()
{
node b(8, 10);
node a(b);
cout<< a.x << " " << a.y << endl;
return 0;
}
运行结果
复制构造函数被调用
8 10
可以看到,先输出了"复制构造函数被调用",之后又执行了打印a.x、a.y的语句。说明,在创建对象a时,使用对象b初始化对象a,是会调用复制构造函数的。
2、函数fun( )的形参是对象时,传递参数时,复制构造函数会被调用
void show(node temp) {
cout << temp.x << " " << temp.y << endl;
}
int main()
{
node a(8, 10);
show(a);
return 0;
}
运行结果
复制构造函数被调用
8 10
可以看到,首先打印的是复制构造函数中的语句“复制构造函数被调用”,之后执行的是函数体里面的打印语句。所以,对象作为函数的参数时,传递参数时,是会调用复制构造函数的。即进行了值复制。 更进一步,如果参数是引用:
void show(node& temp) {
cout << temp.x << " " << temp.y << endl;
}
int main()
{
node a(8, 10);
show(a);
return 0;
}
此时函数的参数不是对象本身,而是对象的引用。再来看一下运行结果:
8 10
如果函数的参数是 对象的引用时,传入参数的时候,没有调用复制构造函数。因为没有输出复制构造函数中的打印语句“复制构造函数被调用”。所以这种情况下,就没有复制这一步,因为传入的是实参的引用。如果大量数据要作为实参传入时,最好传入的是引用。速度快。
函数的返回值是对象时,返回结果时,复制构造函数会被调用
node create_node() {
node temp(3, 5);
return temp;
}
int main()
{
node a = create_node();
cout << a.x << " " << a.y << endl;
return 0;
}
运行结果:
3 5
可以看到,并没有想象的那样输出“复制构造函数被调用”,也就是说明,此种情况下,并没有调用复制构造函数。 原因在于现在的编译器对于“对象作为函数的返回值”这种情况有优化。返回值为对象时,不再产生临时对象,因而不再调用复制构造函数。
|