C++的拷贝构造函数

2024-05-28 2060阅读

拷贝构造函数

  • 前言
  • 一、拷贝构造函数概念
    • 理解
    • 定义
    • 二、拷贝构造函数的特征
    • 三、注意要点
      • 写法
      • 实践
      • 传址返回与引用返回的区别
        • 传址返回
        • 引用返回
        • 传值返回和传址返回的对比
        • 总结
        • 测试

          前言

          推荐一个网站给想要了解或者学习人工智能知识的读者,这个网站里内容讲解通俗易懂且风趣幽默,对我帮助很大。我想与大家分享这个宝藏网站,请点击下方链接查看。

          https://www.captainbed.cn/f1

          类的6个默认成员函数:如果一个类中什么成员都没有,简称为空类。

          空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。

          默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。

          class Date {};
          

          C++的拷贝构造函数 第1张


          一、拷贝构造函数概念

          理解

          在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎。

          C++的拷贝构造函数 第2张

          那在创建对象时,可否创建一个与已存在对象一某一样的新对象呢?

          定义

          拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。

          C++拷贝构造函数是一种特殊的构造函数,用于创建对象时,使用一个已有对象的内容来初始化新的对象。它接受一个同类对象作为参数,并按照该对象的数据成员的值来创建新的对象。

          拷贝构造函数通常用于以下情况:

          • 在创建对象时,使用同类已有对象的值来初始化新对象。
          • 以值传递方式将对象传递给函数。
          • 以值返回方式从函数返回对象。

            拷贝构造函数的定义形式为:

            类名(const 类名&obj)
            {
                // 构造函数的实现
            }
            

            其中,类名是要创建的对象的类名,obj是要拷贝的对象。

            拷贝构造函数的工作原理是将obj的数据成员的值复制给新创建的对象。这意味着新对象的数据成员会与原对象具有相同的值,但是它们是独立的,改变其中一个对象的数据成员的值不会影响另一个对象的数据成员。

            如果没有显式定义拷贝构造函数,编译器会提供一个默认的拷贝构造函数。默认的拷贝构造函数执行的是浅拷贝,即简单地将原对象的值复制给新对象的数据成员。如果类中包含指针类型的数据成员,需要自己定义拷贝构造函数,进行深拷贝,确保指针指向的对象也被复制。

            注意,拷贝构造函数是类成员函数,通常定义在类的公有部分。拷贝构造函数是通过对象名来调用的,而不是通过函数名来调用。

            二、拷贝构造函数的特征

            拷贝构造函数也是特殊的成员函数,其特征如下:

            1. 拷贝构造函数是构造函数的一个重载形式。
            2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。
            class Date
            {
            public:
            	Date(int year = 1900, int month = 1, int day = 1)
            	{
            		_year = year;
            		_month = month;
            		_day = day;
            	}
            	// Date(const Date& d)   // 正确写法
            	Date(const Date d)   // 错误写法:编译报错,会引发无穷递归
            	{
            		_year = d._year;
            		_month = d._month;
            		_day = d._day;
            	}
            private:
            	int _year;
            	int _month;
            	int _day;
            };
            int main()
            {
            	Date d1;
            	Date d2(d1);
            	return 0;
            }
            

            C++的拷贝构造函数 第3张

            3. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。

            和构造函数不一样,构造函数内置类型不会初始化,拷贝构造函数会初始化

            class Time
            {
            public:
            	Time()
            	{
            		_hour = 1;
            		_minute = 1;
            		_second = 1;
            	}
            	Time(const Time& t)
            	{
            		_hour = t._hour;
            		_minute = t._minute;
            		_second = t._second;
            		cout 
            private:
            	// 基本类型(内置类型)
            	int _year = 1970;
            	int _month = 1;
            	int _day = 1;
            	// 自定义类型
            	Time _t;
            };
            int main()
            {
            	Date d1;
            	// 用已经存在的d1拷贝构造d2,此处会调用Date类的拷贝构造函数
            	// 但Date类并没有显式定义拷贝构造函数,则编译器会给Date类生成一个默认的拷贝构造函数
            	Date d2(d1);
            	return 0;
            }
            
            public:
            	Stack(size_t capacity = 10)
            	{
            		_array = (DataType*)malloc(capacity * sizeof(DataType));
            		if (nullptr == _array)
            		{
            			perror("malloc申请空间失败");
            			return;
            		}
            		_size = 0;
            		_capacity = capacity;
            	}
            	void Push(const DataType& data)
            	{
            		// CheckCapacity();
            		_array[_size] = data;
            		_size++;
            	}
            	~Stack()
            	{
            		if (_array)
            		{
            			free(_array);
            			_array = nullptr;
            			_capacity = 0;
            			_size = 0;
            		}
            	}
            private:
            	DataType* _array;
            	size_t _size;
            	size_t _capacity;
            };
            int main()
            {
            	Stack s1;
            	s1.Push(1);
            	s1.Push(2);
            	s1.Push(3);
            	s1.Push(4);
            	Stack s2(s1);
            	return 0;
            }
            
            public:
            	Date(int year, int minute, int day)
            	{
            		cout 
            		cout 
            		cout 
            	Date temp(d);
            	return temp;
            }
            int main()
            {
            	Date d1(2022, 1, 13);
            	Test(d1);
            	return 0;
            }
            
            public:
            	Date(int year = 1900, int month = 1, int day = 1)
            	{
            		_year = year;
            		_month = month;
            		_day = day;
            	}
            	// Date(const Date d)   // 错误写法:编译报错,会引发无穷递归
            	// 正确写法
            	Date(const Date& d)   
            	{
            		_year = d._year;
            		_month = d._month;
            		_day = d._day;
            	}
            private:
            	int _year;
            	int _month;
            	int _day;
            };
            int main()
            {
            	Date d1;
            	Date d2(d1);
            	return 0;
            }
            
            		cout 
            public:
            	Date(int year = 1900, int month = 1, int day = 1)
            	{
            		cout
            		cout 
            		cout 
            	Date temp(d);
            	return temp;
            }
            //Date& fun()
            //{
            //	Date d(2024,4,14);
            //	return d;
            //}
            int main()
            {
            	Date d;
            	func(d);
            	//const Date& ret = func();
            	return 0;
            }
            //class Date
            //{
            //public:
            //	Date(int year, int minute, int day)
            //	{
            //		cout 
            //		cout 
            //		cout 
            //	Date temp(d);
            //	return temp;
            //}
            //int main()
            //{
            //	Date d1(2022, 1, 13);
            //	Test(d1);
            //	return 0;
            //}
            

    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]