C++ constructor initialization sequence details

  • 2020-04-02 02:46:31
  • OfStack

1. Introduction to constructor, destructor and copy constructor

The constructor

A constructor cannot return a value
2. The system will automatically call the default constructor to initialize the object when the default constructor initializes all data members to zero or null
3. When an object is created, the system automatically calls the constructor

The destructor

1. Destructor has no arguments and no return value. Cannot overload, that is, only one destructor can be defined in a class
2. If a destructor is not defined in a class, the system will automatically generate a default destructor
1. The destructor of the class of the object defined in the function body will be automatically called when the function execution ends; 2. An object dynamically built with the new operator when it is released using the delete operator.

Copy constructor

Copy constructors are actually constructors, with all the features of a normal constructor and the same name as the class name. The copy constructor has only one argument, which is a reference to a similar object. It is called in three situations:

1. Initialize another object of the class with a known object of the class;
2. The formal parameter of a function is the object of a class, and the function is called to combine the formal parameter and the argument;
3. The return value of the function is the object of the class, and the caller is returned after the execution of the function.

[code]


/*
version: 1.0
author: hellogiser
date: 2014/9/25
*/ #include "stdafx.h"
#include <iostream>
using namespace std; class point
{
private:
    int x, y;
public:
    point(int xx = 0, int yy = 0)
    {
        x = xx;
        y = yy;
        cout << "Constructor" << endl;
    }
    point(const point &p)
    {
        x = p.x;
        y = p.y;
        cout << "Copy Constructor" << endl;
    }
    ~point()
    {
        cout << "Destructor" << endl;
    }
    int get_x()
    {
        return x;
    }
    int get_y()
    {
        return y;
    }
};
void f(point p)
{
    // copy constructor
    cout << p.get_x() << "  " << p.get_y() << endl;
    // destructor
} point g()
{
    point a(7, 33); //constructor
    return a; // copy constructor    temp object
} void test()
{
    point a(15, 22); // constructor
    point b(a); //(1) copy constructor
    cout << b.get_x() << "  " << b.get_y() << endl; // 15 22
    f(b);//  (2) copy constructor
    b = g(); // (3) copy constructor
    cout << b.get_x() << "  " << b.get_y() << endl; // 7  33
} int main()
{
    test();
    return 0;
}
/*
Constructor
Copy Constructor
15      22
Copy Constructor
15      22
Destructor
Constructor
Copy Constructor
Destructor
Destructor
7       33
Destructor
Destructor
*/

2. Constructor execution order in inheritance relationships

(1) constructors of any virtual base class are constructed in the order in which they are inherited;
(2) constructors of any non-virtual base class are constructed in the order in which they are inherited;
(3) the constructor of any member object (data member) is called in the order in which they are declared;
(4) class's own constructor (self).

[code]


/*
version: 1.0
author: hellogiser
date: 2014/9/27
*/ #include "stdafx.h"
#include <iostream>
using namespace std;
class OBJ1
{
public:
    OBJ1()
    {
        cout << "OBJ1n";
    }
}; class OBJ2
{
public:
    OBJ2()
    {
        cout << "OBJ2n";
    }
}; class Base1
{
public:
    Base1()
    {
        cout << "Base1n";
    }
}; class Base2
{
public:
    Base2()
    {
        cout << "Base2n";
    }
}; class Base3
{
public:
    Base3()
    {
        cout << "Base3n";
    }
}; class Base4
{
public:
    Base4()
    {
        cout << "Base4n";
    }
}; class Derived : public Base1, virtual public Base2,
    public Base3, virtual public Base4
{
public:
    Derived() : Base4(), Base3(), Base2(),
        Base1(), obj2(), obj1()
    {
        cout << "Derived.n";
    }
protected:
    OBJ1 obj1;
    OBJ2 obj2;
}; void test()
{
    Derived aa;
    cout << "This is ok.n";
} int main()
{
    test();
    return 0;
}
/*
Base2
Base4
Base1
Base3
OBJ1
OBJ2
Derived.
This is ok.
*/

[code 2]


/*
version: 1.0
author: hellogiser
date: 2014/9/27
*/ #include "stdafx.h"
#include <iostream>
using namespace std; class Base1
{
public:
    Base1(int i)
    {
        cout << "Base1 " << i << endl;
    }
}; class Base2
{
public:
    Base2(int i)
    {
        cout << "Base2 " << i << endl;
    }
}; class Base3
{
public:
    Base3()
    {
        cout << "Base3 *" << endl;
    }
}; class Derived : public Base2,  public Base1, virtual public Base3
{
public:
    Derived(int a, int b, int c, int d, int e)
        : Base1(a), b2(d), b1(c), Base2(b)
    {
        m = e;
        cout << "Derived.n";
    }
protected:
    Base1 b1;
    Base2 b2;
    Base3 b3;
    int m;
}; void test()
{
    Derived aa(1, 2, 3, 4, 5);
    cout << "This is ok.n";
} int main()
{
    test();
    return 0;
}
/*
Base3 *
Base2 2
Base1 1
Base1 3
Base2 4
Base3 *
Derived.
This is ok.
*/

Analysis:

(1) virtual

By inheritance: Base3

Step 1: inherit Base3 first. If Base3() is not found in the initialization list, call the default constructor Base3() in Base3, and print "Base3.   *"

(2) non - virtual

In order of inheritance: Base2, Base1

Step 2: inherit Base2, find Base2(b) in the initialization list, call Base2's constructor Base2(2), and print "Base2 2"

Step 3: inherit Base1, find Base1(a) in the initialization list, call Base1's constructor Base1(1), and print "Base1 1"

  (3) the data member

In order of declaration: b1,b2,b3

Step 4: construct b1, find b1(c) in the initialization list, call Base1 constructor Base1(3), print "Base1 3"

Step 5: construct b2, find b2(d) in the initialization list, call Base2's constructor Base1(4), and print "Base2 4"

Step 6: construct b3, where b3() is not found in the initialization list, call Base3's constructor Base3(), and print "Base3 *"

(4) the self

Step 7: execute your own constructor body and output "Derived."


Related articles: