如果类的设计者不写复制构造函数,编译器就会自动生成复制构造函数。大多数情况下,其作用是实现从源对象到目标对象逐个字节的复制,即使得目标对象的每个成员变量都变得和源对象相等。编译器自动生成的复制构造函数称为“默认复制构造函数”。
#include<iostream >
class Complex
{
public:
double real, imag;
Complex(double r, double i) {
real= r; imag = i;
}//构造函数
};
int main(){
Complex cl(1, 2);
Complex c2 (cl); //用默认复制构造函数初始化c2
cout<<c2.real<<","<<c2.imag; //输出 1,2
return 0;
}
如果编写了复制构造函数,则默认复制构造函数就不存在了。下面是一个非默认复制构造函数的例子。
#include<iostream>
using namespace std;
class Complex{
public:
double real, imag;
Complex(double r,double i){
real = r; imag = i;
}
Complex(const Complex & c){
real = c.real; imag = c.imag;//复制构造函数
cout<<"Copy Constructor called"<<endl ;
}
};
int main(){
Complex cl(1, 2);
Complex c2 (cl); //调用复制构造函数
cout<<c2.real<<","<<c2.imag;
return 0;
}
如果有复制的需要用系统默认的复制构造函数即可,我们自己定义的复制构造函数除了进行复制操作还可以进行其他操作(后话)
构造函数不能以本类的对象作为唯一参数,以免和复制构造函数相混淆。例如,不能写如下构造函数:
Complex (Complex c) {...}
复制构造函数被调用的三种情况
- 当用一个对象去初始化另一个对象时
Time p1 = p2;
Time p1(p2);
这两条语句是等价的,其次要区分复制和赋值语句,复制是左边没有定义的,赋值是左边有定义的,也就是会不会调用赋值构造函数的区别 - 如果函数F的参数是类A的对象,那么当F被调用时,类A的复制构造函数将被调用,换句话讲,形参的初始化也是靠实参调用拷贝构造函数进行的
#include<iostream>
using namespace std;
class A{
public:
A(){};
A(A & a){
cout<<"Copy constructor called"<<endl;
}
};
void Func(A a){ }
int main(){
A a;
Func(a);
return 0;
}
我们只是要初始化,如果再用复制构造函数初始化一个对象时间上有点划不来,
所以就像我们之前说的参数改为const Time&c既不会被改变又节省资源。
- 如果函数的返冋值是类 A 的对象,则函数返冋时,类 A 的复制构造函数被调用。换言之,作为函数返回值的对象是用复制构造函数初始化 的,而调用复制构造函数时的实参,就是 return 语句所返回的对象。例如下面的程序:
#include<iostream>
using namespace std;
class A {
public:
int v;
A(int n) { v = n; };
A(const A & a) {
v = a.v;
cout << "Copy constructor called" << endl;
}
};
A Func() {
A a(4);
return a;
}
int main() {
cout << Func().v << endl;
return 0;
}
//以上内容大部分转自C++拷贝构造函数(复制构造函数)详解 (biancheng.net)
网站标题:CV鼻祖洋芋
原创文章,作者:locus,如若转载,请注明出处:https://blog.cvpotato.cn/forward-code/c/221/
本博客所发布的内容,部分为原创文章,转载注明来源,网络转载文章如有侵权请联系站长!