c++primer 3/12----复制构造函数

C++ 支持两种初始化形式):直接初始化和复制初始化。复制初始化使用 = 符号,而直接初始化将初始化式放在圆括号中。

当形参或返回值为类类型时,由复制构造函数进行复制

string make_plural(size_t, const string&, const string&);

这个函数隐式使用 string 复制构造函数返回给定单词的复数形式。形参是 const 引用,不能复制。

复制构造函数可用于初始化顺序容器中的元素。
vector<string> svec(5);

编译器首先使用 string 默认构造函数创建一个临时值来初始化 svec,然后使用复制构造函数将临时值复制到svec 的每个元素。

如果没有为类类型数组提供元素初始化式,则将用默认构造函数初始化每个元素。然而,如果使用常规的花括号括住的数组初始化列表(第 4.1.1 节)来提供显式元素初始化式,则使用复制初始化来初始化每个元素。根据指定值创建适当类型的元素,然后用复制构造函数将该值复制到相应元素:

     Sales_item primer_eds[] = { string("0-201-16487-6"),
                                 string("0-201-54848-8"),
                                 string("0-201-82470-1"),
                                 Sales_item()
                               };

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

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

制构造函数就是接受单个类类型引用形参(通常用 const 修饰)的构造函数:

     class Foo {
     public:
        Foo();           // default constructor
        Foo(const Foo&); // copy constructor
        // ...
     };

无须显式地定义复制构造函数,也可以复制。

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

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

与复制构造函数一样,如果类没有定义自己的赋值操作符,则编译器会合成一个。

例如,Sales_item 的赋值操作符可以声明为:

     class Sales_item {
     public:
         // other members as before
         // equivalent to the synthesized assignment operator
         Sales_item& operator=(const Sales_item &);
     };

合成赋值操作符与合成复制构造函数的操作类似。它会执行逐个成员赋值:右操作数对象的每个成员赋值给左操作数对象的对应成员。除数组之外,每个成员用所属类型的常规方式进行赋值。对于数组,给每个数组元素赋值。

As an example, the synthesized Sales_item assignment operator would look something like:

例如,Sales_item 的合成赋值操作符可能如下所示:

     // equivalent to the synthesized assignment operator
     Sales_item&
     Sales_item::operator=(const Sales_item &rhs)
     {
         isbn = rhs.isbn;              // calls string::operator=
         units_sold = rhs.units_sold;  // uses built-in int assignment
         revenue = rhs.revenue;        // uses built-in double assignment
         return *this;
     }

可以使用合成复制构造函数的类通常也可以使用合成赋值操作符。我们的 Sales_item 类无须定义复制构造函数或赋值操作符,而,类也可以定义自己的赋值操作符。一般而言,如果类需要复制构造函数,它也会需要赋值操作符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值