C++ 复制功能

本文详细解析了C++中复制功能的核心概念,包括拷贝构造函数和赋值操作符的作用,以及如何在不同场景下正确使用这些功能。通过多个实例展示了编译器的默认行为和用户自定义复制函数的影响,并提供了显示调用基类复制函数的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ 复制功能

       说C++复制功能,它可能不是很熟悉。类中的拷贝构造函数和赋值操作符。可是其实或许我们一不小心就会忽略编译器所做的一些默认操作。引起晦涩的错误。以下分析几种场景:


一、场景一:所有默认

#include<stdio.h>
class base{
public:
	base(){}
	base(int dt):data(dt){}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};
class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};
int main()
{
	derived da(1,5);
	derived db(2,10);
	da.get();
	db.get();

	da = db;
	da.get();
	db.get();

	derived dc(da);
	dc.get();

	base ba(da);
	ba.get();
	getchar();
}
结果:


    假设在编译器中执行程序,我们知道,当调用复制函数是。除了派生类的成员被复制外。基类的成员也被复制。这是编译器的行为,当用户未定义复制行为时,编译器就会主动提供一个默认版本号同一时候在须要的时候悄悄的调用完毕复制工作。



场景二、基类默认,派生类自己定义

#include<stdio.h>
class base{
public:
	base(){}
	base(int dt):data(dt){}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};
class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	derived(const derived&d)
	{
		printf("call derived::copy construct function.\n");
		ddata = d.ddata;
	}
	derived& operator=(const derived&d)
	{
		printf("call derived::operator= function.\n");
		ddata = d.ddata;
		return *this;
	}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};
结果:


    从结果能够看出,当用户定义了复制函数时。一切默认行为就不会发生,即派生类中不会隐式调用基类的默认复制函数。


场景三、基类自己定义,派生类默认

#include<stdio.h>
class base{
public:
	base(){}
	base(int dt):data(dt){}
	base(const base&b)
	{
		printf("call base::copy construct function.\n");
		data = b.data;
	}
	base& operator=(const base&d)
	{
		printf("call base::operator= function.\n");
		data = d.data;
		return *this;
	}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};

class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};
结果:


    从结果能够看出。当派生类没有显示定义复制函数时,那么他就会调用默认的复制函数,而默认复制函数会自己主动调用基类的复制函数。


场景四、基类派生类都自己定义

#include<stdio.h>
class base{
public:
	base(){}
	base(int dt):data(dt){}
	base(const base&b)
	{
		printf("call base::copy construct function.\n");
		data = b.data;
	}
	base& operator=(const base&d)
	{
		printf("call base::operator= function.\n");
		data = d.data;
		return *this;
	}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};

class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	derived(const derived&d):base(d)
	{
		printf("call derived::copy construct function.\n");
		ddata = d.ddata;
	}
	derived& operator=(const derived&d)
	{
		printf("call derived::operator= function.\n");
		ddata = d.ddata;
		return *this;
	}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};

结果:


    从结果看出,仅仅要定义了派生类的复制函数,那么就不会隐式调用基类的复制函数。


结论:仅仅要派生类定义了复制函数,那么就不会隐式调用基类的复制函数,所以在这样的情况下。我们必须显示调用基类的复制函数,以免造成复制的不完整。

以下给出显示调用的样例:

class base{
public:
	base(){}
	base(int dt):data(dt){}
	base(const base&b)
	{
		printf("call base::copy construct function.\n");
		data = b.data;
	}
	base& operator=(const base&d)
	{
		printf("call base::operator= function.\n");
		data = d.data;
		return *this;
	}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};

class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	derived(const derived&d):base(d)
	{
		printf("call derived::copy construct function.\n");
		ddata = d.ddata;
	}
	derived& operator=(const derived&d)
	{
		printf("call derived::operator= function.\n");
		base::operator=(d);
		ddata = d.ddata;
		return *this;
	}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};
结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值