拷贝构造函数剖析【C++】
【摘要】 @TOC知识点:解释:拷贝构造函数是一种特殊的构造函数,它具有一般构造函数的所有特性,但其形参是本类对象的引用。作用:使用一个已经存在的对象(由拷贝构造函数参数指定)去初始化同类的一个新对象。定义格式:构造函数名 (&类名);三种使用情况:用一个对象去初始化同类的另一个对象;函数的形参是类的对象,调用函数时形参与实参的结合;函数返回值是类的对象,函数执行返回调用;注意:拷贝构造函数的参数采用...
@TOC
知识点:
解释:拷贝构造函数是一种特殊的构造函数,它具有一般构造函数的所有特性,但其形参是本类对象的引用。
作用:使用一个已经存在的对象(由拷贝构造函数参数指定)去初始化同类的一个新对象。
定义格式:构造函数名 (&类名);
三种使用情况:
- 用一个对象去初始化同类的另一个对象;
- 函数的形参是类的对象,调用函数时形参与实参的结合;
- 函数返回值是类的对象,函数执行返回调用;
注意:
- 拷贝构造函数的参数采用引用方式。若把一个真实的类对象作为参数传到拷贝构造函数,引起无穷递归;
- 拷贝构造函数的名字必须与类名相同,且无返回值;
- 拷贝构造函数只有一个参数,必须为本类对象的引用;
- 每一个类必须有一个拷贝构造函数。若用户定义类时未给出拷贝构造函数,则系统会自动产生一个缺省的拷贝构造函数;
该例重点阐述:为什么拷贝构造函数的参数必须为同类对象的引用?
#include <iostream>
using namespace std;
class Complex {
private:
double real, image;
public:
Complex(double r, double i); //声明构造函数
Complex(Complex &c); //声明拷贝构造函数
Complex add(Complex c);
void Output();
};
Complex::Complex(double r, double i): real(r), image(i) { //构造函数初始化列表
cout << "调用两个参数的构造函数" << endl;
}
Complex::Complex(Complex &c) {
real = c.real;
image = c.image;
cout << "调用拷贝构造函数" << endl;
}
void Complex::Output() {
cout << "(" << real << "," << image << ")" << endl;
}
Complex Complex::add(Complex c) {
Complex y(real + c.real, image + c.image);
return y;
}
void f(Complex n) {
cout << "n=";
n.Output();
}
int main() {
Complex a(3.0, 4.0), b(5.6, 7.9); //创建Complex类的两个对象a,b
Complex c(a); //使用拷贝构造函数,用已创建的对象a初始化要建立的另一个对象c
cout << "a=";
a.Output();
cout << "c=";
c.Output();
f(b);
c = a.add(b);
c.Output();
}
程序运行结果:
调用两个参数的构造函数
调用两个参数的构造函数
调用拷贝构造函数
a=(3,4)
c=(3,4)
调用拷贝构造函数
n=(5.6,7.9)
调用拷贝构造函数
调用两个参数的构造函数
(8.6,11.9)
- 本例中,当程序执行到main()函数 Complex c(a); 语句时,程序会到拷贝构造函数完成“用存在的类对象a,初始化c的工作”。但是,若此时拷贝构造函数的参数是一个真实的类对象而非同类对象的引用,则无法完成对类对象c的初始化工作。
- 因为没有一块儿内存空间去接收传递的对象,&c就相当于是a的一个别称,该临时对象用于完成对c的赋值,拷贝构造函数定义中 real=c.real; real就是c的实部,c.real就是用a的实部去给c的实部赋值,虚部部分同理,所以会无限次调用该函数,即引起无穷递归。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)