📜  C++中构造函数/析构函数调用的顺序

📅  最后修改于: 2021-05-30 14:57:54             🧑  作者: Mango

先决条件:构造函数
每当我们创建类的对象时,该类的默认构造函数都会自动调用以初始化该类的成员。
如果我们从另一个类继承一个类并创建派生类的对象,则很明显,将调用派生类的默认构造函数,但在此之前,将调用所有基类的默认构造函数,即顺序调用的方式是先调用基类的默认构造函数,然后再调用派生类的默认构造函数。
为什么在创建派生类的对象时调用基类的构造函数?

要理解这一点,您将不得不回忆起关于继承的知识。当一个类从另一个继承时会发生什么?基类的数据成员和成员函数根据访问说明符自动进入派生类,但这些成员的定义仅存在于基类中。因此,当我们创建派生类的对象时,必须初始化派生类的所有成员,但派生类中的继承成员只能由基类的构造函数初始化,因为这些成员的定义仅存在于基类中。这就是为什么首先调用基类的构造函数以初始化所有继承的成员的原因。

CPP
// C++ program to show the order of constructor call
// in single inheritance
  
#include 
using namespace std;
 
// base class
class Parent
{
    public:
     
    // base class constructor
    Parent()
    {
        cout << "Inside base class" << endl;
    }
};
 
// sub class
class Child : public Parent
{
    public:
     
    //sub class constructor
    Child()
    {
        cout << "Inside sub class" << endl;
    }
};
 
// main function
int main() {
      
    // creating object of sub class
    Child obj;
     
    return 0;
}


CPP
// C++ program to show the order of constructor calls
// in Multiple Inheritance
 
#include 
using namespace std;
 
// first base class
class Parent1
{  
    
    public:
     
    // first base class's Constructor   
    Parent1()
    {
        cout << "Inside first base class" << endl;
    }
};
 
// second base class
class Parent2
{
    public:
     
    // second base class's Constructor
    Parent2()
    {
        cout << "Inside second base class" << endl;
    }
};
 
// child class inherits Parent1 and Parent2
class Child : public Parent1, public Parent2
{
    public:
     
    // child class's Constructor
    Child()
    {
        cout << "Inside child class" << endl;
    }
};
 
// main function
int main() {
     
    // creating object of class Child
    Child obj1;
    return 0;
}


CPP
// C++ program to show how to call parameterised Constructor
// of base class when derived class's Constructor is called
 
#include 
using namespace std;
 
// base class
class Parent {
    int x;
 
public:
    // base class's parameterised constructor
    Parent(int i)
    {
        x = i;
        cout << "Inside base class's parameterised "
                "constructor"
             << endl;
    }
};
 
// sub class
class Child : public Parent {
    int j;
 
public:
    // sub class's parameterised constructor
    Child(int x)
        : Parent(j)
        , j(x)
    {
        cout << "Inside sub class's parameterised "
                "constructor"
             << endl;
    }
};
 
// main function
int main()
{
 
    // creating object of class Child
    Child obj1(10);
    return 0;
}


输出:

Inside base class
Inside sub class

构造函数调用多重继承的顺序

对于构造函数调用的多重继承顺序为,先按继承顺序调用基类的构造函数,然后再按派生类的构造函数进行调用。

CPP

// C++ program to show the order of constructor calls
// in Multiple Inheritance
 
#include 
using namespace std;
 
// first base class
class Parent1
{  
    
    public:
     
    // first base class's Constructor   
    Parent1()
    {
        cout << "Inside first base class" << endl;
    }
};
 
// second base class
class Parent2
{
    public:
     
    // second base class's Constructor
    Parent2()
    {
        cout << "Inside second base class" << endl;
    }
};
 
// child class inherits Parent1 and Parent2
class Child : public Parent1, public Parent2
{
    public:
     
    // child class's Constructor
    Child()
    {
        cout << "Inside child class" << endl;
    }
};
 
// main function
int main() {
     
    // creating object of class Child
    Child obj1;
    return 0;
}

输出:

Inside first base class
Inside second base class
Inside child class

构造函数和析构函数的顺序调用给定的继承顺序

如何在派生类构造函数中调用基类的参数化构造函数?

要在调用派生类的参数化构造函数时调用基类的参数化构造函数,必须在派生类中显式指定基类的参数化构造函数,如以下程序所示:

CPP

// C++ program to show how to call parameterised Constructor
// of base class when derived class's Constructor is called
 
#include 
using namespace std;
 
// base class
class Parent {
    int x;
 
public:
    // base class's parameterised constructor
    Parent(int i)
    {
        x = i;
        cout << "Inside base class's parameterised "
                "constructor"
             << endl;
    }
};
 
// sub class
class Child : public Parent {
    int j;
 
public:
    // sub class's parameterised constructor
    Child(int x)
        : Parent(j)
        , j(x)
    {
        cout << "Inside sub class's parameterised "
                "constructor"
             << endl;
    }
};
 
// main function
int main()
{
 
    // creating object of class Child
    Child obj1(10);
    return 0;
}

输出:

Inside base class's parameterised constructor
Inside sub class's parameterised constructor

重要事项

  • 每当调用派生类的默认构造函数时,都会自动调用基类的默认构造函数。
  • 要在子类的参数化构造函数中调用基类的参数化构造函数,我们必须明确地提及它。
  • 无法在子类的默认构造函数中调用基类的参数化构造函数,而应在子类的参数化构造函数中调用它。
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”