前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >拷贝构造函数:对象复制的重要工具

拷贝构造函数:对象复制的重要工具

作者头像
洁洁
发布2023-12-07 13:36:14
1300
发布2023-12-07 13:36:14
举报
文章被收录于专栏:小洁叫你mysql小洁叫你mysql

拷贝构造函数

功能: 使用一个已经存在的对象来初始化一个新的同一类型的对象。 声明: 只有一个参数并且参数为该类对象的引用 如果类中没有说明拷贝构造函数,则系统会自动生成一个缺省复制构造函数,作为该类的公有成员。

当函数的形参是类的对象,调用函数时,进行形参与实参结合时便用。 这时要在内存新建立一个局部对象,并把实参拷贝到新的对象中。理所当然也调用拷贝构造函数。

代码语言:javascript
复制
  1 #include"copy.h"
  2 /*void function(const person& p)
  3 {
  4     cout<<"constructor"<<endl;
  5 }*/
  6 void function2(const person p)
  7 {
  8     cout<<"constructor"<<endl;
  9 }
 10 
 11 int main()
 12 {
 13     person p(10,20);
 14     person pp(p);
 15     person ppp = pp;
 16 
 17     function2(p);
 18     return 0;
 19 }

结果:

代码语言:javascript
复制
[bsk@localhost structor]$ ./a.out 
person constructor //p的默认构造调用
copy function10  //pp的拷贝构造调用
copy function10 //ppp的拷贝构造调用
copy function10 //function函数拷贝构造
constructor

那如果函数参数时以引用的方式,会不会调用拷贝构造函数呢?

代码语言:javascript
复制
  1 #include"copy.h"
  2 void function(const person& p)
  3 {
  4     cout<<"constructor"<<endl;
  5 }
  6 int main()
  7 {
  8     person p(10,20);
  9     person pp(p);
 10     person ppp = pp;
 11 
 12     function(p);
 13     return 0;
 14 }

结果如下:

代码语言:javascript
复制
[bsk@localhost structor]$ ./a.out 
person constructor //p的默认构造调用
copy function10  //pp的拷贝构造调用
copy function10 //ppp的拷贝构造调用
constructor   //function函数调用

当函数的返回值是类对象,函数执行完成返回调用者时使用。理由也是要建立一个临时对象中,再返回调用者。

代码语言:javascript
复制
#include"copy.h"

person function3(const person& p)
{
    return p;
}

int main()
{
    person p(10,20);
    function3(p);
    return 0;
}

结果:

代码语言:javascript
复制
[bsk@localhost structor]$ ./a.out 
person constructor  //p的默认构造
copy function10   //function 在返回类对象时调用的拷贝构造

为什么不直接用要返回的局部对象呢?因为局部对象在离开建立它的函数时就消亡了,不可能在返回调用函数后维续生存,所以在处理这种情况时,编译系统会在调用函数的表达式中创建一个无名临时对象,该临时对象的生存周期只在函数调用处的表达式中。如果用一个新变量来接收临时对象, 临时对象变成有名对象,则此对象就不会马上销毁

所谐return对象,实际上是调用拷贝构造函数把该对象的值拷入临时对象。如果返回的是变量,处理过程类似,只是不调用构造函数

代码语言:javascript
复制
#include"copy.h"

const person& function3(const person& p)
{
    return p;
}

int main()
{
    person p(10,20);
  
  person  pp = function3(p);
  const person & ppp= function(p);//因为引用,共用一块内存空间,不会调用拷贝构造函数
    return 0;
}

结果:

代码语言:javascript
复制
[bsk@localhost structor]$ ./a.out 
person constructor  //p的默认构造
copy function10   //  pp = function3(p);拷贝构造

深浅拷贝

深拷贝指的是在进行对象复制时,不仅复制了对象本身,还复制了对象所引用的其他对象,以确保复制后的对象与原始对象完全独立,彼此之间不会相互影响。换句话说,深拷贝会递归地复制对象及其所有引用的对象,从而创建一份全新的、独立的副本。

举个例子,假设有一个包含其他对象引用的复杂对象A,通过深拷贝后得到的副本B将会包含与A中相同类型和值的所有对象,而不是简单地复制它们的引用。这意味着对副本B的任何修改都不会影响原始对象A,因为它们引用的是完全独立的对象。

在编程中,实现深拷贝通常需要递归遍历对象结构,并对其中的每个对象进行复制。对于复杂的数据结构,如嵌套的列表、字典或自定义对象,确保进行深拷贝尤为重要。

深拷贝能够确保对象复制的完整性和独立性,但也需要额外的系统资源来完成复制操作。因此,在进行对象复制时,需要权衡资源消耗和需求,选择适合的复制方式。

代码语言:javascript
复制
#include<iostream>
using namespace std;
class person
{
public:
	person()
	{
		cout << "person()的默认构造" << endl;
	}
	person(int age,int hight)
	{
		myage = age;
		myheight =new int( hight);
		cout << "person()的有参函数构造" << endl;
	}
	//shenkaobei
	person(const person& p)
	{
		myage = p.myage;
		//myheight = p.myheight;编译器默认(浅拷贝)提供的
		//因为是指针地址,会导致两个名释放同一块内存空间
		//深拷贝
		myheight = new int(*p.myheight);
	}
	~person()
	{
		//析构函数将,堆区 ,开辟的数据进行释放
		if (myheight != NULL)
		{
			delete myheight;
			myheight = NULL;
		}
		cout << "person()的析构函数构造" << endl;
	}
	int myage;
	int* myheight;
};
void test01()
{
	person p1(10,120);


	person p2(p1);
	cout << p2.myage<<endl <<*p2.myheight<< endl;
	return;
}
int main()
{
	test01();
	system("pause");
	return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 拷贝构造函数
  • 深浅拷贝
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档