C++13.1.2合成复制构造函数----定义复制对象时会发生什么

本文深入探讨了复制构造函数的概念及其实现方式,包括合成构造函数的功能、如何定义自定义复制构造函数以及如何禁止对象的复制。同时介绍了复制构造函数在不同场景下的应用。

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

简介

  • 复制构造函数:就是构造函数的一种,只是形参是const类类型的引用。——— Sale_item(const Sale_item &orig)
//合成赋值操作符函数(下一节)
Sale_item& Sale_item::operator=(const Sale_item &rhs){//类外定义成员函数不要忘记加上类作用域Sale_item::
      isbn=rhs.isbn;//逐个进行复制
      units_sold=rhs.units_sold;
      revenue=rhs.revenue;
      return *this;//返回被赋值的那个对象
      //赋值操作符函数函数名写法:"operator ="
      //函数返回类型:类类型的引用Sale_item&
      //形参:const 类类型的引用
}
//合成复制构造操函数
Sale_item::Sale_item(const Sale_item &orig):

isbn(orig.isbn),

units_sold(orig.units_sold),

revenue(orig.revenue)

{}


//因为是构造函数,所以函数名是类名,无返回值。因为是复制构造函数,所以形参是const类类型的引用,对里面的每个元素进行复制。
//这个函数是在类外定义,所以加上类作用域Sale_item::
//**(感觉和具有初始化列表的构造函数差不多,只是形参不同,这里的形参是const类类型的引用)**
  • 用const类类型的引用做形参相当于是类的一个别名(想象一下const 普通类型的引用做形参)

  • 但是有些类必须对复制对象时发生的事情加以控制

    • 这样的类经常有一个数据成员是指针;
    • 或者有成员表示在构造函数中分配的其他资源。而另一些类在创建新对象时必须做一些特定工作。
  • 这两种情况,都必须定义复制构造函数

  • 但是有些类需要完全禁止复制。如iostream类就不允许复制。如果想要禁止复制,似乎可以省略复制构造函数,然而,如果不定义复制构造函数,编译器会默认合成一个。

  • 为了防止复制,类必须显示声明其复制构造函数为private

-如果复制构造函数是私有的,将不允许用户代码复制该类类型的对象,编译器将拒绝任何进行复制的尝试。

  • 然而,类的友元和成员仍然可以访问,即仍然可以复制,如果想要连友元和成员中的复制也禁止,就可以声明一个private复制构造函数但不对其定义。

=========================================================================================================================

一、合成构造函数

  • 如果我们没有定义复制构造函数,编译器会为我们合成一个(默认的)。与合成的默认构造函数(12.4.1)不同,即使我们定义了其他构造函数,也会合成复制构造函数。合成复制构造函数是执行逐个成员初始化,将新对象初始化为原对象的副本。

  • 所谓逐个成员指的是编译器将现有对象的每个非static成员,依次复制到正在创建的对象。只有一个例外,每个成员的类型决定了复制该成员的含义,合成复制构造函数直接复制内置类型成员的值,类类型成员使用该类的复制构造函数进行复制。数组成员的复制是个例外,虽然一般不能复制数组,但如果一个类具有数据成员,则合成复制构造函数将复制数组,复制数组合成构造函数将复制数组的每一个元素。

class Sale_item{
private:
   std::string isbn;
   int unit_sold;
   double revenue;
};
//合成的复制构造函数
Sale_item::Sale_item(const Sale_item &orig):
isbn(orig.isbn),units_sold(orig.units_sold),revenue(orig.revenue)
{}

二、定义自己的复制构造函数

  • 复制构造函数就是接受单个类类型引用形参(const)的构造函数
clss Foo{
public:
   Foo();
   Foo(const Foo&);//声明一个复制构造函数,首先是构造函数,所以名称和类名一样,再者形参必须是const的类类型的引用

};
  • 无需显示定义复制构造函数。
  • 但是有些类必须对复制对象时发生的事情加以控制。这样的类经常有一个数据成员是指针,或者有成员表示在构造函数中分配的其他资源。而另一些类在创建新对象时必须做一些特定工作。这两种情况,都必须定义复制构造函数

  • 认识到什么情况下需要定义复制构造函数是困难的。复制构造函数也是构造函数,所以,没有返回值,名称与类名相同,可以(而且应)使用构造函数初始化列表初始化新创建对象的成员,可以在函数体中做任何其他必要工作。

三、禁止复制

  • 有些类需要完全禁止复制。如iostream类就不允许复制。如果想要禁止复制,似乎可以省略复制构造函数,然而,如果不定义复制构造函数,编译器会默认合成一个。

  • 为了防止复制,类必须显示声明其复制构造函数为private

-如果复制构造函数是私有的,将不允许用户代码复制该类类型的对象,编译器将拒绝任何进行复制的尝试。

  • 然而,类的友元和成员仍然可以访问,即仍然可以复制,如果想要连友元和成员中的复制也禁止,就可以声明一个private复制构造函数但不对其定义。
  • 声明而不定义成员函数是合法的,但是,使用未定义成员的任何尝试将导致链接失败。通过声明但不定义private复制构造函数,可以禁止任何复制类类型对象的尝试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值