C++中基类和派生类的构造函数与析构函数的调用顺序分析

基类为B,派生类为C,直接上代码以及运行结果。

目录

思路分析

代码一

运行结果一

 代码二:B(i)改为b(i)

运行结果二

 代码三:加上B(i)

运行结果三

 代码四:删掉C类定义的B对象b,删除b(i)

运行结果四


思路分析

经评论区提醒,5月13日补充思路:首先,要知道基类和派生类的构造函数执行顺序是先执行基类的构造函数,再执行派生类的构造函数;而析构函数的执行顺序与构造函数的执行顺序刚好相反

其次,如果在派生类的构造函数中显式指定了调用基类的哪个构造函数,就会先执行这个构造函数;如果没有指定,则会调用基类的默认构造函数。

最后要注意的是,代码中的派生类C,除了继承一个基类B的整型变量b之外,还自定义了一个基类B的对象b,而这个对象b还包括了一个整型变量b,这三个b要注意区分。

为了方便,我们称B类的b变量为b1,C类的b对象的b变量为b2。

代码一中,由于C的构造函数显示指定了调用B的带参数的构造函数,所以会先输出“B`s constructor called.”,此时b1=i=5;然后由于C中定义的B类对象b并没有指定构造函数,所以会调用B类默认的构造函数,输出“B`s default constructor called.”,此时b2=0;然后调用C的带参构造函数,输出“C`s default constructor called.”,同时使得c的值为6;然后执行C类的Print函数,先执行B类的Print函数,输出b1的值为5,再输出c的值为6。最后按照与执行构造函数相反的顺序执行析构函数。

代码二中由于将B(i)改成了b(i),显示指定了C类的b对象调用的构造函数,而基类B调用哪个构造函数并没有被指定,因此先调用B类的默认构造函数,使得b1=0;然后调用C类的b对象的带参数的构造函数,使得b2=5;然后调用C的带参构造函数,同时使得c的值为6;然后执行C类的Print函数,先输出b1的值0,再输出c的值6;最后按照与执行构造函数相反的顺序执行析构函数。

代码三中由于加上了B(i),因此会先显示调用基类B的带参构造函数,再显示调用C类b对象的带参数的构造函数,使得b1=5,b2=5;然后调用C的带参构造函数,同时使得c的值为6;C类的Print函数先输出b1的值5,再输出c的值6;最后按照与执行构造函数相反的顺序执行析构函数。

代码四中,删掉C类定义的B对象b,删除b(i),因此只会显示调用基类B的带参构造函数,使得b1的值为5;然后调用C的带参构造函数,同时使得c的值为6;C的Print函数会先输出b1的值5,再输出c的值6;最后按照与执行构造函数相反顺序执行析构函数。

代码一

#include <iostream>
using namespace std;

class B{
public:
    B();
    B(int i);
    ~B();
    virtual void Print();
private:
    int b;
};
B::B(){
    b=0;
    cout<<"B`s default constructor called."<<endl;
}
B::B(int i){
    b=i;
    cout<<"B`s constructor called."<<endl;
}
B::~B(){
    cout<<"B`s destructor called."<<endl;
}
void B::Print(){
    cout<<b<<endl;
}

class C:public B{
public:
    C();
    C(int i,int j);
    ~C();
    void Print();
private:
    int c;
    B b;
};

C::C(){
    c=0;
    cout<<"C`s default constructor called."<<endl;
}
C::C(int i,int j):B(i){
    c=j;
    cout<<"C`s constructor called."<<endl;
}
C::~C(){
    cout<<"C`s destructor called."<<endl;
}
void C::Print(){
    B::Print();
    cout<<c<<endl;
}

int main()
{
    C obj(5,6);
    obj.Print();
    return 0;
}

运行结果一

 代码二:B(i)改为b(i)

#include <iostream>
using namespace std;

class B{
public:
    B();
    B(int i);
    ~B();
    virtual void Print();
private:
    int b;
};
B::B(){
    b=0;
    cout<<"B`s default constructor called."<<endl;
}
B::B(int i){
    b=i;
    cout<<"B`s constructor called."<<endl;
}
B::~B(){
    cout<<"B`s destructor called."<<endl;
}
void B::Print(){
    cout<<b<<endl;
}

class C:public B{
public:
    C();
    C(int i,int j);
    ~C();
    void Print();
private:
    int c;
    B b;
};

C::C(){
    c=0;
    cout<<"C`s default constructor called."<<endl;
}
C::C(int i,int j):b(i){
    c=j;
    cout<<"C`s constructor called."<<endl;
}
C::~C(){
    cout<<"C`s destructor called."<<endl;
}
void C::Print(){
    B::Print();
    cout<<c<<endl;
}

int main()
{
    C obj(5,6);
    obj.Print();
    return 0;
}

运行结果二

 代码三:加上B(i)

#include <iostream>
using namespace std;

class B{
public:
    B();
    B(int i);
    ~B();
    virtual void Print();
private:
    int b;
};
B::B(){
    b=0;
    cout<<"B`s default constructor called."<<endl;
}
B::B(int i){
    b=i;
    cout<<"B`s constructor called."<<endl;
}
B::~B(){
    cout<<"B`s destructor called."<<endl;
}
void B::Print(){
    cout<<b<<endl;
}

class C:public B{
public:
    C();
    C(int i,int j);
    ~C();
    void Print();
private:
    int c;
    B b;
};

C::C(){
    c=0;
    cout<<"C`s default constructor called."<<endl;
}
C::C(int i,int j):B(i),b(i){
    c=j;
    cout<<"C`s constructor called."<<endl;
}
C::~C(){
    cout<<"C`s destructor called."<<endl;
}
void C::Print(){
    B::Print();
    cout<<c<<endl;
}

int main()
{
    C obj(5,6);
    obj.Print();
    return 0;
}

运行结果三

 代码四:删掉C类定义的B对象b,删除b(i)

#include <iostream>
using namespace std;

class B{
public:
    B();
    B(int i);
    ~B();
    virtual void Print();
private:
    int b;
};
B::B(){
    b=0;
    cout<<"B`s default constructor called."<<endl;
}
B::B(int i){
    b=i;
    cout<<"B`s constructor called."<<endl;
}
B::~B(){
    cout<<"B`s destructor called."<<endl;
}
void B::Print(){
    cout<<b<<endl;
}

class C:public B{
public:
    C();
    C(int i,int j);
    ~C();
    void Print();
private:
    int c;
};

C::C(){
    c=0;
    cout<<"C`s default constructor called."<<endl;
}
C::C(int i,int j):B(i){
    c=j;
    cout<<"C`s constructor called."<<endl;
}
C::~C(){
    cout<<"C`s destructor called."<<endl;
}
void C::Print(){
    B::Print();
    cout<<c<<endl;
}

int main()
{
    C obj(5,6);
    obj.Print();
    return 0;
}

运行结果四

猜你喜欢

转载自blog.csdn.net/KK_2018/article/details/130586810