【C++】详解拷贝构造

这篇具有很好参考价值的文章主要介绍了【C++】详解拷贝构造。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

拷贝构造的功能

写法:

拷贝构造函数的参数为什么是引用类型

系统自动生成的拷贝构造函数

拷贝构造的深拷贝与浅拷贝

概念

浅拷贝:

深拷贝

小结


拷贝构造的功能

拷贝构造函数可以把曾经实例化好的对象的数据拷贝给新创建的数据 ,可见说拷贝构造函数在功能上是构造函数的另一种形式。都是让对象初始化。

写法:

拷贝构造函数在语法层是构造函数的重载,函数名就是类名,无返回值,参数是该类类型对象的引用(为了保护被引用对象数据不被破坏,会在类型前面加上const)

 Date(const Date& d) //以日期类为例,定义拷贝构造的写法
Date d1;
 Date d2(d1); //以日期类为例,实例化对象时的写法

Date d1;

Date d2 = d1;  //以日期类为例,实例化对象时的另一种写法

拷贝构造函数的参数为什么是引用类型

下面是定义的日期类的拷贝构造函数,但参数并不是引用类型

Date(const Date d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

因为是传值,实例化对象时需要调用拷贝构造函数把数据拷贝过来,但拷贝数据函数的参数又需要掉用拷贝构造函数,如此就死循环了,拷贝构造函数会被无限调用。如图所示【C++】详解拷贝构造,C++,javascript,开发语言,ecmascript,c++,算法这种情况编译器会强制报错

【C++】详解拷贝构造,C++,javascript,开发语言,ecmascript,c++,算法

【C++】详解拷贝构造,C++,javascript,开发语言,ecmascript,c++,算法

系统自动生成的拷贝构造函数

若未显式定义,编译器会生成默认的拷贝构造函数 默认的拷贝构造函数对象按内存存储 按字节序 完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝
下面代码中定义了一个时间类 Time ,又定义了一个日期类 Date , 时间类在日期类里实例化了对象_t,_t就是日期类的自定义类型,但并没有定义日期类的拷贝构造函数。那么系统自动生成的拷贝构造函数会怎么处理自定义类型_t和内置类型的年月日呢?
class Time {   //时间类
public:

Time() 
   {
_hour = 1;
_minute = 1;
_second = 1;
}

Time(const Time& t) //自定义时间类的拷贝构造函数
{
_hour = t._hour;
_minute = t._minute;
_second = t._second;
}

private:

int _hour;
int _minute;
int _second;
};

class Date  //日期类,但没有自定义拷贝构造函数
{
	
private:
// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;

// 自定义类型
Time _t;  //时间类实例化对象 _t
	
};

int main(){

Date d1;
Date d2(d1); //拷贝对象d1的数据

 // 用已经存在的d1拷贝构造d2,此处会调用Date类的拷贝构造函数
    // 但Date类并没有显式定义拷贝构造函数,则编译器会给Date类生成一个默认的拷贝构造函数

return 0;
}



只需明晰一点即可,系统自动生成的默认拷贝构造对内置类型进行浅拷贝对自定义类型,会调用自定义类型的拷贝构造函数,若自定义类型并未定义拷贝构造函数,系统便会自动生成。

下图是代码执行示意图【C++】详解拷贝构造,C++,javascript,开发语言,ecmascript,c++,算法

下图是逻辑示意图【C++】详解拷贝构造,C++,javascript,开发语言,ecmascript,c++,算法

拷贝构造的深拷贝与浅拷贝

概念

浅拷贝:

又称值拷贝,是按字节序拷贝的,通俗的讲别的数据长啥样就拷贝啥样。

浅拷贝的细节:下面代码中还是定义了一个日期类,但增加了一个int*的变量它指向一块空间。这是让默认构造函数进行浅拷贝会发生什么呢?

class Date //日期类,并没有定义拷贝构造函数
{
public:

	Date()//构造函数
	{
		_year = 1;
		_month = 1;
		_day = 1;
			_a = (int*)malloc(sizeof(int) * 7); //开辟空间并把空间的值初始化
			for (int i = 0; i < 7; i++)
			{
				_a[i] = 0;
			}
	}

private:
	int _year;
	int _month;
	int _day;
	int* _a; //指向一块空间
};
int main()
{
	Date d; 
	Date d1(d); //拷贝d的值
}

结果:d对象和d1对象的数据会一模一样,如下图【C++】详解拷贝构造,C++,javascript,开发语言,ecmascript,c++,算法

我们发现d对象的值和d1对象的值一模一样,并且d对象中的_a和d1对象中的_a都指向同一块空间。如下图

【C++】详解拷贝构造,C++,javascript,开发语言,ecmascript,c++,算法

上述就值浅拷贝的坏处,d1对象的_a并没有申请资源而是直接指向了d对象_a的空间,如果想让d1

_a也申请空间就需要深拷贝,想要深拷贝就需要自己定义一个拷贝构造函数,该拷贝构造函数如何申请空间要根据不同的场景具体实现。

深拷贝

下面的代码是对上面代码的改造,

class Date
{
public:

	Date() //构造函数
	{
		_year = 1;
		_month = 1;
		_day = 1;
			_a = (int*)malloc(sizeof(int) * 7);
			for (int i = 0; i < 7; i++)
			{
				_a[i] = 0;
			}
	}

	Date(const Date& d) //拷贝构造函数
	{
		_year = d._year; 
		_month = d._month;
		_day = d._day;

		_a = (int*)malloc(sizeof(int) * (sizeof(d._a) / sizeof(d._a[0])));  //开辟空间

			for (int i = 0; i < (sizeof(d._a) / sizeof(d._a[0])); i++)  //赋值
			{
				_a[i] = d._a[i];
			}
	}

private:
	int _year;
	int _month;
	int _day;
	int* _a;
};
int main()
{
	Date d;
	Date d1(d);
}

d1对象的_a会独自开空间并且拷贝d对象的数据,如下图【C++】详解拷贝构造,C++,javascript,开发语言,ecmascript,c++,算法这样就完成了拷贝构造的深拷贝了。

小结

拷贝构造是构造函数的重载。参数是该类类型的引用(一般会加上const),不加引用在逻辑是会让拷贝函数无限调用,此时编译器会报错。如果未显示定义拷贝构造函数,编译器会生成默认的拷贝构造函数默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。浅拷贝又称值拷贝,是按字节序拷贝的,通俗的讲别的数据长啥样就拷贝啥样。而深拷贝会申请资源(空间)再赋值。

另外我还为大家准备了几篇不错的博客

构造函数:  

希尔排序:   

堆排序的时间复杂度:  文章来源地址https://www.toymoban.com/news/detail-856838.html

到了这里,关于【C++】详解拷贝构造的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 『C++成长记』拷贝构造函数

     🔥 博客主页: 小王又困了 📚 系列专栏: C++ 🌟 人之为学,不日近则日退 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 目录 一、拷贝构造函数 📒1.1拷贝构造函数的概念 📒1.2拷贝构造函数的写法 📒1.3编译器生成的拷贝构造 📒1.4拷贝构造函数的用法 📒1.5拷贝构造函数典型调

    2024年02月04日
    浏览(41)
  • 【C++学习】类和对象 | 拷贝构造 | 探索拷贝构造函数为什么需要引用传参 | 深拷贝 | 初识运算符重载

    上一篇文章我们开始学习类内的默认成员函数, 这里是传送门,有兴趣可以去看看:http://t.csdn.cn/iXdpH 这篇文章我们继续来学习类和对象的知识。 目录 写在前面: 1. 拷贝构造 2. 拷贝构造函数为什么需要引用传参? 3. 深拷贝 4. 初识运算符重载 写在最后: 我们在创建一个对

    2024年02月11日
    浏览(53)
  • 【C++杂货铺】拷贝构造函数

    📖 定义 拷贝构造函数 是构造函数的一个重载 ,它的本质还是 构造函数 ,那就意味着,只有在创建对象的时候,编译器才会自动调用它,那他和普通的构造函数有什么区别呢? 拷贝构造函数,是创建对象的时候,用一个已存在的对象,去初始化待创建的对象 。简单来说,

    2024年02月16日
    浏览(52)
  • 【C++初阶】类和对象——构造函数&&析构函数&&拷贝构造函数

    ========================================================================= 个人主页点击直达: 小白不是程序媛 C++系列专栏: C++头疼记 ========================================================================= 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性 析构函数 概念 析构函数特性 拷贝构

    2024年02月06日
    浏览(57)
  • C++ 类和对象(二)构造函数、析构函数、拷贝构造函数

            本文将介绍类的6个默认成员函数中的构造函数、析构函数和拷贝构造函数,赋值重载和取地址重载涉及运算符重载的知识,将在下篇讲解。所谓默认成员函数,也就是每个类都有的成员函数,我们可以显式定义这些函数,否则,编译器会自动生成它们。 目录 前言

    2024年02月09日
    浏览(46)
  • C++奇迹之旅:深入思考拷贝构造函数

    在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎。 那在创建对象时,可否创建一个与已存在对象一某一样的新对象呢? 拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动

    2024年04月26日
    浏览(38)
  • 【C++】C++入门—初识构造函数 , 析构函数,拷贝构造函数,赋值运算符重载

    如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗? 并不是 任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数 我们实现了,编译器就不会生成了 构造函数是

    2024年02月21日
    浏览(50)
  • 【C++】类与对象(构造函数、析构函数、拷贝构造函数、常引用)

       🌈个人主页: 秦jh__https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343 🔥 系列专栏:   目录 类的6个默认成员函数 构造函数 特性  析构函数 特性  析构的顺序 拷贝构造函数 特性 常引用      💬 hello! 各位铁子们大家好哇。              今日更新了类与对象的构造函数、

    2024年02月21日
    浏览(46)
  • c++拷贝构造与赋值运算符重载

    目录 目录:         1:拷贝构造         2:赋值运算符重载                  前言:在上一章我们已经学习过了,构造与析构这两个默认成员函数了,接下来让我们一起来学习另外两个重要的默认成员函数。         首先让我们来讲一下默认成员函数这个概念,所谓

    2024年02月08日
    浏览(54)
  • [C++ 从入门到精通] 11.拷贝构造函数

    📢博客主页:https://loewen.blog.csdn.net 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📢本文由 丶布布 原创,首发于 CSDN, 转载注明出处 🙉 📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨ 一. 定义 拷贝构造函数 :如果一个类构造区数的 第一个参数是所属

    2024年02月21日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包