【C++修行之道】类和对象(三)拷贝构造函数

2024-06-08 1377阅读

目录

一、 概念

二、特征

 正确的拷贝构造函数写法:

拷贝函数的另一种写法 

三、若未显式定义,编译器会生成默认的拷贝构造函数。

四、编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?

深拷贝的写法:

五、拷贝构造函数典型调用场景:

六、总结:


一、 概念

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

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

【C++修行之道】类和对象(三)拷贝构造函数

二、特征

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

  1. 拷贝构造函数是构造函数的一个重载形式。
  2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。
  3. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
  4. 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?当然像日期类这样的类是没必要的。那么下面的类呢?验证一下试试?
  5. 拷贝构造函数典型调用场景:
  • 使用已存在对象创建新对象
  • 函数参数类型为类类型对象
  • 函数返回值类型为类类型对象
    class Date
    {
    public:
    	Date(int year = 1900, int month = 1, int day = 1)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
        Date(const Date& d) // 正确写法
        {
    	    // this->_year = d._year;
    	    _year = d._year;
        	_month = d._month;
    	    _day = d._day;
        }
    	Date(Date& d)// 错误写法: 它不能用于从常量对象或临时对象进行拷贝构造
    	{
    		_year = d._year;
    		_month = d._month;
    		_day = d._day;
    	}
    	Date(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;
    }
    

     正确的拷贝构造函数写法:

    Date(const Date& d) // 正确写法
    {
    	// this->_year = d._year;
    	_year = d._year;
    	_month = d._month;
    	_day = d._day;
    }

    这是正确的拷贝构造函数写法。它接受一个对Date类型的常量引用作为参数,这意味着它可以用于从常量对象、非常量对象甚至是临时对象进行拷贝构造。由于它的灵活性,这是最常用的拷贝构造函数定义方式。

    	Date(Date& d)
    	{
    		_year = d._year;
    		_month = d._month;
    		_day = d._day;
    	}
    • 不能接收常量对象:这个构造函数只接受非常量引用(Date&),这意味着你不能使用它来拷贝一个常量对象。如果试图这样做,编译器会报错,因为常量对象不能被非常量引用所绑定。
    • 不能接收临时对象:在C++中,临时对象(也称为右值)经常出现在表达式中,例如函数返回值或者类型转换的结果。由于这个拷贝构造函数不接受右值引用或常量引用,因此它不能用于拷贝这些临时对象。
    • 发生错误操作时没有报错:赋值反了

      【C++修行之道】类和对象(三)拷贝构造函数

          Date(Date d)// 错误写法:编译报错,会引发无穷递归
      	{
      		_year = d._year;
      		_month = d._month;
      		_day = d._day;
      	}

      这个构造函数是错误的,会引发无穷递归。原因在于,当试图用这个构造函数创建一个Date对象时,它会尝试以值传递的方式接收一个Date对象作为参数。为了构造这个参数对象d,又需要调用拷贝构造函数,这会导致无限递归调用,最终耗尽栈空间并导致程序崩溃。 

      【C++修行之道】类和对象(三)拷贝构造函数

      【C++修行之道】类和对象(三)拷贝构造函数

      【C++修行之道】类和对象(三)拷贝构造函数

      class Date
      {
      public:
      	Date(int year, int month, int day)
      	{
      		_year = year;
      		_month = month;
      		_day = day;
      	}
      	/*Date(Date& d)
      	{
      		d._year = _year;
      		d._month = _month;
      		d._day = _day;
      	}*/
      	// Date d3(d2);
      	//Date(const Date& d)
      	//{
      	//	// this->_year = d._year;
      	//	_year = d._year;
      	//	_month = d._month;
      	//	_day = d._day;
      	//}
      	Date(Date* d)
      	{
      		_year = d->_year;
      		_month = d->_month;
      		_day = d->_day;
      	}
      	void Print()
      	{
      		cout 
VPS购买请点击我

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

目录[+]