Copy constructor of C++ copy control

Reprinted from: http://www.cnblogs.com/QG-whz/p/4485574.html

The handling of the array members of the class by the copy constructor mentioned in this blog is where I have been puzzled before. Reprint it as a note.


Updated July 26:

  Looking back after such a long time, I found that there were several mistakes in the article (marked in red):

  1.   A constructor does not have only one parameter, it can also be in the form of multiple parameters, the second parameter and subsequent parameters are supplied with a default value.
  2.   It is not that the compiler will help the class declaration when the copy control function is not declared, and certain conditions need to be met.

 

《《=========================================================================》》

 

C++ classes use three special member functions: copy constructors, assignment operators, and destructors to determine what happens during initialization or assignment between class objects. The so-called "copy control" is to control the process of object copying through these three member functions. This article will introduce the copy constructor. 

  • copy constructor

what is copy constructor

   A copy constructor is first and foremost a constructor, which like all other constructors has the same name as the class and has no return value. It has a single parameter (error) , which is a reference to the class type (usually it is declared as const , since the object used for assignment generally does not change its own value). So the prototype of the copy constructor is:

copy code
class BOOK
{
    public:
     BOOK( const BOOK& rhs); // Constructor 1 
     BOOK( string &name, float price = 0 ):_bookName(name),_price(price){}; // Constructor 2 
     BOOK():_price( 0 ) ,_bookName( "" ){}; // Constructor three 

  private :    float _price ;    string _bookName;   // .... };
copy code

 

when is it called

   The copy constructor is called when a class object needs to be copied. These calls can be summarized as:

  1. An object is explicitly or implicitly initialized from an object of the same type.

    When defining a new object and initializing it with an object of the same type, the copy constructor is used explicitly, as in:

BOOK book1;
BOOK book2(book1);

    The copy constructor is implicitly called when an object of that type is passed to or returned from a function.

  1. Arguments passed as values ​​are passed to a function.
  2. Copy an object when the function returns.
  3. Initialize the elements in the order container.

   Such as:

    vector<string> svec(5);

 

  编译器首先调用string类默认构造函数创建一个临时值,再用复制构造函数将临时值复制到每一个元素。

  1. 根据元素初始化列表初始化数组元素。

  如:

copy code
BOOK books[]={
  string("book1"),
  string("book2"),
  string("book3"),
  BOOK()
};
copy code

 

  book数组的前三个元素将调用构造函数二进行隐式类型转换(C++隐式类型转换),然后调用复制构造函数进行数组元素的复制。如果类禁止隐式类型转换(构造函数使用了explicit声明),或希望不指定实参或多个实参,需要使用完整的构造函数语法,如数组最后一个元素的初始化。

 

如果没有为类声明复制构造函数会怎样

      如果你没有声明一个复制构造函数,那么编译器会给声明一个。实际上,如果你自己没有声明,编译器会为类声明一个复制构造函数,一个赋值操作符以及一个析构函数,此外如果你没有声明任何构造函数的话,编译器也会为你声明一个合成默认构造函数。(错误)所有这些编译器自动生成的类成员函数皆为pubilc  inline。(这部分内容可以参考《Effective C++》条款05)编译器创建的复制构造函数单纯地将来源对象的每一个非static成员拷贝到目标对象,这在很多时候是不能满足类需求的,特别是类中含有指针时,这时候就需要我们自己来写复制控制的三个特殊成员函数了。

 

编译器合成的复制构造函数做了什么

  合成复制构造函数的行为是:对每一个非static成员进行逐个成员初始化。成员类型不同,初始化方式不一样:

内置类型(如int):直接复制值。

类类型:调用该类的复制构造函数进行复制。

数组:这个比较特殊,因为我们知道一般不能复制数组,但在类中,复制数组时合成复制构造函数将复制数组的每一个值。

另外,合成复制构造函数对类数据成员的初始化都是放在构造函数初始化列表中进行的。

 

禁止复制

 

      如果我们想禁止某个类的复制行为,我们当然不会想去定义一个复制构造函数,然而编译器却会自动为我们定义一个,那么到底该如何阻止一个类的复制行为呢?

      We can define the copy constructor as private , which does not allow user code to copy objects of this class type, which will cause an error at compile time. However, friends and members of a class can still be copied. The solution is that we can declare a private copy constructor without defining it. When a class member or friend attempts to copy, an error will occur at runtime.

Summary: In order to reject the function automatically provided by the compiler, the corresponding member function can be declared as private and not implemented. (For details, please refer to Article 06  of " Effective C++ ". If you do not want to use the functions automatically generated by the compiler, you should explicitly refuse)


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324838661&siteId=291194637