03-02拷贝构造函数

拷贝构造函数

一种特殊的构造函数:

  • 形参是本类对象的引用
  • 作用:用一个已存在的对象,初始化另一个同类的对象
  • 也是构造函数的函数重载

调用:

  • 通过=复制对象时,系统自动调用

特点:

  1. 函数名,同类名
  2. 没有返回值类型
  3. 只有一个参数,是同类对象的引用class& obj
  4. 每个类必须有一个拷贝构造函数
    1. 若没有显式定义,系统会自动生成缺省的拷贝构造函数
    2. 缺省的拷贝构造函数,将对象的各个数据成员拷贝给被拷贝对象的各个数据成员;两个对象的内存映像是一模一样的
    3. 缺省拷贝构造函数按成员逐一复制的过程,自动完成

一般形式:

#include <iostream>
using namespace std;
class Point {
private:
	int x, y;
public:
	Point(int x_, int y_)	//构造函数
    {
		x = x_; y = y_;
		cout << "use normal constructor" << endl;
	}
	Point(Point& p)		//拷贝构造函数
    {
		x = p.x; y = p.y;
		cout << "use copy constructor" << endl;
	}
};
int main()
{
	Point p1(2, 3);		//调用普通构造函数
	Point p2(p1);		//“代入法”调用拷贝构造函数
	Point p3 = p2;		//“赋值法”调用拷贝构造函数

	return 0;
}

调用的三种情况

  • 使用拷贝构造函数初始化对象时
Point p2(p1);		//“代入法”调用拷贝构造函数
Point p3 = p2;		//“赋值法”调用拷贝构造函数
  • 函数形参是类的对象,调用函数时,形参与实参结合时
f1(Point p)
{
	p.show();
}
int main()
{
	Point p;
	f1(p);		//当调用函数,进行形参和实参结合时,调用拷贝构造函数
	return 0;
}
  • 函数的返回值是对象,函数执行完成,返回对象给调用者时
Point f2()
{
	Point p(0,0);
	return p;
}
int main()
{
	Point p=f2();	//函数的返回值是对象,函数执行完成,返回对象给调用者时
	return 0;
}

浅拷贝和深拷贝

浅拷贝:缺省的拷贝构造函数,对数据成员逐一赋值

  • 实质是同一地址

  • 若类有指针型数据,会产生错误

#include <iostream>
using namespace std;
class A {
private:
	char* name;
	int id;
public:
	A(const char* name_, int id_) {
		id = id_;
		name = new char[strlen(name_) + 1];
		if (name != 0)	strcpy(name, name_);
		cout << "constructing..." << name << endl;
	}
	~A() {
		cout << "destructing..." << name << endl;
		name[0] = '\0';
		delete name;
	}
};
int main()
{
	A a1("asd", 5);
	A a2 = a1;
	return 0;
}
/*
output:
constructing...asd
destructing...asd
destructing...乱码
编译器报错
*/

深拷贝:显式定义的拷贝构造函数,使之不仅拷贝数据成员,而且为拷贝对象和被拷贝对象分配各自的内存空间

  • 不同地址
class A {
private:
	char* name;
	int id;
public:
	A(const char* name_, int id_) {
		id = id_;
		name = new char[strlen(name_) + 1];
		if (name != 0)	strcpy(name, name_);
		cout << "constructing..." << name << endl;
	}
	A(A& a) {
		id = a.id;
		name = new char[strlen(a.name) + 1];
		if (name != 0)	strcpy(name, a.name);
		cout << "constructing..." << name << endl;
	}
	~A() {
		cout << "destructing..." << name << endl;
		name[0] = '\0';
		delete name;
	}
};
/*
output:
constructing...asd
constructing...asd
destructing...asd
destructing...asd
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值