Construction operation of copy constructor for C + + object model

Source: Internet
Author: User
Tags bitwise

the copy constructor is used to construct a new object based on an existing object.
1. When the constructor is calledThere are three situations where an object is constructed with the contents of one object as the initial value of another class's object, namely:1) When initializing an object for display, such asclass X {...};x x;x xx = x;//or x XX (x);2) When an object is passed as a parameter to a function3) When the function returns an object of a class
2. Default member Replication initializationIf class does not provide an explicit copy constructor, when the object of class is constructed with another object as the initial value, the interior is done in this way: for a member variable of a basic type, such as int, an array, copy from one object to another using bit copy For a member variable of a class type, its copy constructor is called recursively.
3. When the copy constructor is synthesized by the compilerwhen the copy constructor is necessary, it is constructed by the compiler. What is the time when it is necessary? This means that when class does not show the so-called bitwise copy semantics (bit-wise copy semantics).
as with the default constructor, if class does not declare a copy constructor, an implicitly-declared or implicitly-defined copy constructor appears. The copy constructors are divided into trivial (useless) and nontrivial (useful). Only nontrivial copy constructors are synthesized by the compiler. The criterion for determining whether a copy constructor is trivial is whether the class exhibits bitwise copy semantics.
The following explains what is bitwise copy semantics.
4, bitwise copy semantics (bit-wise copy)in the following code snippet:
Class person{public    : Person        (const char *name, int.);    Private:        char *mname;        int mAge;}; int main () {person    p1 ("P1", "a");    Person P2 (p1);    return 0;}

In the code snippet above, p2 is initialized according to P1. The class person does not define a copy constructor, and according to the definition of the class person, its member variables are all basic types of variables (pointers and int), there are no member variables of class type, no virtual functions are defined, nor are they derived classes of a class. At this point, the copy construction operation can be done by bit-wise replication (also the default copy operation). So in this case the definition of the class shows bitwise copy semantics, so it does not synthesize a copy constructor.
The following is a discussion of the circumstances under which a class behaves as a non-bitwise copy semantics.
5, non-bitwise copy semanticsThe following four cases do not show the bitwise copy semantics. These are listed below and explained in detail.
1) When class contains a member object, and the object's classes declare the copy constructor (whether explicitly declared or compiled)when the person class is defined as follows:
Class person{public    : Person        (const String &name, int.);    Private:        String mname;        int mAge;}; Class string{public    :        string (const char *STR)        string (const string &rhs);    Private:        char *mstr;        int Mlen;};

because the person class does not explicitly define a copy constructor, it contains a member object (MSTR), and the Class (String) that the object belongs to defines a copy constructor, so the person at this point exhibits a non-bitwise copy Semantics. The compiler synthesizes a copy constructor for it, which calls the copy constructor of string to complete the initialization of the member variable MSTR and the initialization of the other base type's member variable (MAGE) by bit-wise replication.
2) When class inherits from a base class, and the base class has a copy constructor (whether explicitly declared or compiled)For example, the following code fragment:
Class Student:public person{public    :        Student (const String &name, int age, int no);    Private:        int mNo;};

as mentioned earlier, the class person has a copy constructor for a compiler composition because there is a member variable of type string. The class student inherits from the class person, so in this case, the class student shows the non-bitwise copy semantics. The compiler synthesizes a copy constructor for it, which calls the copy constructor of its base class to complete the initialization of the base class part, and then initializes the member variables of its derived class.
3) When class declares one or more virtual functionswhen a virtual function is declared in a class, the compiler supports the virtual function mechanism and, at compile time, does the following:1. Add a virtual function table (VTBL) containing the address of each function virtual function. 2. Insert a pointer to the Class virtual function table (VPTR) in each object of the class.
in order to implement the virtual function mechanism correctly, the compiler must set its initial value correctly for each newly generated class object vptr. So the compiler has to synthesize a copy constructor to properly initialize the vptr.
Add a virtual function print to the class person and class student as follows:
Class person{public    : Person        (const char *name, int.);        Virtual ~person ();        virtual void print ();    Private:        const char *mname;        int mAge;}; Class Student:public person{public    :        Student (const char *name, int age, int no);        Virtual ~student ();        virtual void print ();    Private:        int mNo;};

now consider the following code:
Student S1 ("S1", 22, 1001); Student s2 = S1; Note 1Person P1 = S1; NOTE 2

when an object of a class is constructed with the initial value of another object of that class, the vptr of the two objects should point to the virtual function table of the class, and it is safe to copy the vptr of the other object to the object vptr. So in this case, it can be done using bitwise copy semantics. For example, in the code above, note 1 corresponds to this case.
However, when an object of a class is constructed with an object of its derived class as the initial value, copying the vptr values of the derived class objects directly into the vptr of the base class object can cause significant errors. For example, in the code above, note 2 corresponds to this case. In this case, the copy constructor that the compiler synthesizes for a class must explicitly set the vptr of the class object to the virtual function table of the class, rather than copy the value of the vptr of its derived class object directly, and copy the initialized object's members correctly based on the type of the class.
In General, the compiler synthesizes a copy constructor that correctly sets the point of the vptr pointer of its object according to the type of object.
4) When class derives from an inherited string chain, where there is one or more virtual base classesthe existence of the virtual base class requires special handling. When an object of one class is constructed with another object as the initial value, and the latter has a virtual base class sub-object, the bitwise copy semantics is invalidated. Each compiler causes the location of the virtual base class sub-object in the derived class object to be ready during execution (such as g++ placing the virtual base class sub-object at the end of the derived class object), and bitwise copy semantics may break that position. So the compiler has to make a judgment in its own composition of the copy constructor.
For example, in the following code:
Class base{public    :        Base () {mbase =;}        Virtual ~base () {}        virtual void print () {}        int mbase;}; Class Vbase:virtual public base{public    :        vbase () {mvbase = 101;}        Virtual ~vbase () {}        virtual void print () {}        int mvbase;}; Class Derived:public vbase{public    :        Derived () {mderived = 102;}        Virtual ~derived () {}        virtual void print () {}        int mderived;};

consider the following code:
Vbase vb1; Vbase vb2 = VB1;

as discussed at point 3rd, if the object of one class is constructed with an initial value for another object of the class, then the bitwise copy semantics is used to complete the related operation. The problem still occurs when an object of a derived class is initialized with the initial value of its base class object.
consider the following code:
Derived D; Vbase vb = D;

in this case, in order to complete the initial setting of VB completely correctly, the compiler must synthesize a copy constructor, and place some code to complete the initialization of some member variables of its base class object according to the object of the derived class, and set the value of the vptr of the base class correctly.
in g++, for example, the memory distribution of objects of class derived is probably as follows:
The memory distribution of objects of class vbase is probably as follows:
the memory structure diagram from class derived and class Vbase makes it very easy to see that using bitwise copy semantics does not complete an object that constructs a base class with an object of a derived class as the initial value. Compile the copy constructor of the composition, copy the member variables (mvbase) from the base class sub-object of the class derived object D to the Class Vbase object VB Corresponding member variable, The member variables (mbase) in the virtual base class sub-object of object D are then copied to the corresponding member variable in the object VB (that is, the yellow part of the initialization diagram is copied). Finally, set the two vptr of the object VB to point to the correct location.
Note: The two vptr of class derived are not equal to the two vptr of class vbase, and they are not equal to the vptr of class base.
the code for traversing objects of more than three three classes using the following code is as follows:Note: Operating environment: 32-bit Ubuntu 14.04,g++4.8.2
int main () {    Derived D;    Vbase vb = D;    int *p = (int*) &d;    for (int i = 0; i < sizeof (d)/sizeof (int); ++i)    {        cout << *p << Endl;        ++p;    }    p = (int*) &vb;    cout << Endl;    for (int i = 0; i < sizeof (VB)/sizeof (int); ++i)    {        cout << *p << Endl;        ++p;    }    Base b;    cout << Endl;    p = (int*) &b;    for (int i = 0; i < sizeof (b)/sizeof (int); ++i)    {        cout << *p << Endl;        ++p;    }    return 0;}

its output is as follows:

As You can see from the running results , all the vptr of the three classes are different.

Construction operation of copy constructor for C + + object model

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.