c++继承中的构造与析构方法是什么

发布时间:2022-01-12 22:06:17 作者:iii
来源:亿速云 阅读:159

这篇文章主要讲解了“c++继承中的构造与析构方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“c++继承中的构造与析构方法是什么”吧!

        我们思考下这个问题:如何初始化父类成员?父类构造函数和子类构造函数有何关系呢?在子类中可以定义构造函数,子类构造函数必须对继承而来的成员进行初始化:a> 直接通过初始化列表或者赋值的方式进行初始化;b> 调用父类构造函数进行初始化。

        下来我们来说说父类构造函数在子类中的调用方式,分为两种:a> 默认调用:适用于无参构造函数和使用默认参数的构造函数;b> 显示调用:通过初始化列表进行调用,适用于所有父类构造函数。那么隐式调用是在子类的构造函数中啥都不加,显示调用时在子类构造函数后加上父类构造函数,如下所示

c++继承中的构造与析构方法是什么

        下来我们就对子类的构造函数一探究竟

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    Parent(string s)
    {
        cout << "Parent(string s): " << s << endl;
    }
};

class Child : public Parent
{
public:
    Child()
    {
        cout << "Child()" << endl;
    }
    
    Child(string s) : Parent(s)
    {
        cout << "Child(string s): " << s << endl;
    }
};

int main()
{
    Child c;
    
    Child cc("cc");
    
    return 0;
}

        我们先来分析下,在子类 Child 中,它定义的第一个构造函数显然是隐式调用父类的构造函数。但是在父类的构造函数中,我们既没有定义无参构造函数,也没有定义默认参数的构造函数,所以这个隐式调用肯定会出错。而第二个对象 cc 是进行显示调用的,所以它不会报错。我们来看看编译结果

c++继承中的构造与析构方法是什么

        它报错说第 19 行出错,也就是子类的隐调用出错了,下来我们在父类中通过一个无参构造函数,来看看编译是否还会出错呢

c++继承中的构造与析构方法是什么

        我们看到编译通过了,并且也完美运行。我们来说说子类对象的构造规则:a> 子类对象在创建时会首先调用父类的构造函数;b> 先执行父类的构造函数再执行子类的构造函数;c> 父类构造函数可以被隐式调用或者显示调用。那么子类对象的创建时构造函数的调用又有什么顺序呢?1、调用父类的构造函数;2、调用成员变量的构造函数;3、调用类自身的构造函数。对此,有唐长老总结的一个口诀心法:先父母,后客人,再自己

        下来我们通过编程来看看子类创建时构造函数的执行顺序

#include <iostream>
#include <string>

using namespace std;

class Object
{
    string ms;
public:
    Object(string s)
    {
        ms  = s;
        
        cout << "Object(string s): " << ms << endl;
    }
};

class Parent : public Object
{
    string ms;
public:
    Parent() : Object("Default")
    {
        ms = "Default";
    
        cout << "Parent()" << endl;
    }

    Parent(string s) : Object(s)
    {
        ms = s;
    
        cout << "Parent(string s): " << s << endl;
    }
};

class Child : public Parent
{
    Object mOb1;
    Object mOb2;
    string ms;
public:
    Child() : mOb1("Default 1"), mOb2("Default 2")
    {
        ms = "Default";
    
        cout << "Child()" << endl;
    }
    
    Child(string s) : Parent(s), mOb1(s + " 1"), mOb2(s + " 2")
    {
        ms = s;
        
        cout << "Child(string s): " << s << endl;
    }
};

int main()
{
    Child c;
    
    // c output:
    //   Object(string s): Default
    //   Parent()
    //   Object(string s): Default 1
    //   Object(string s): Default 2
    //   Child()
    
    cout << endl;
    
    Child cc("cc");
    
    // cc output:
    //   Object(string s): Default
    //   Parent(string s) : cc
    //   Object(string s): cc 1
    //   Object(string s): cc 2
    //   Child(string s): cc
    
    return 0;
}

        我们来分析下,类Child c 创建时首先会隐式调用它的父类构造函数 Parent() : Object("Default"),而 Parent 创建时会先调用它的父类 Object 的构造函数 Object("Default")。再来调用成员对象 mOb1 和 mOb2 的构造函数 mOb1("Default 1"), mOb2("Default 2"),最后调用自己的构造函数 Child()。所以最后打印的应该和我们程序中写的是一致的。再来看看对象 cc 的创建过程,因为它是显示调用,所以会调用构造函数 Parent(s) ,而 Parent 的父类 Object 也会调用构造函数 Object(string s) 。额庵后调用成员对象 mOb1 和 mOb2 的构造函数 mOb1(s + "1"), mOb2(s + "2"),最后调用自己的构造函数 Child(string s)。打印的应该也和我们在程序中写的一致。我们来看编译结果

c++继承中的构造与析构方法是什么

        结果和我们分析的是一致的。那么再来看看析构函数的调用顺序,它跟构造函数的顺序刚好相反:1、执行自身的析构函数;2、执行成员变量的析构函数;3、执行父类的析构函数。依旧是在上面的程序基础之上,来看看析构函数的执行顺序。

#include <iostream>
#include <string>

using namespace std;

class Object
{
    string ms;
public:
    Object(string s)
    {
        ms  = s;
        
        cout << "Object(string s): " << ms << endl;
    }
    
    ~Object()
    {
        cout << "~Object() : " << ms << endl;
    }
};

class Parent : public Object
{
    string ms;
public:
    Parent() : Object("Default")
    {
        ms = "Default";
    
        cout << "Parent()" << endl;
    }

    Parent(string s) : Object(s)
    {
        ms = s;
    
        cout << "Parent(string s): " << s << endl;
    }
    
    ~Parent()
    {
        cout << "~Parent() : " << ms << endl;
    }
};

class Child : public Parent
{
    Object mOb1;
    Object mOb2;
    string ms;
public:
    Child() : mOb1("Default 1"), mOb2("Default 2")
    {
        ms = "Default";
    
        cout << "Child()" << endl;
    }
    
    Child(string s) : Parent(s), mOb1(s + " 1"), mOb2(s + " 2")
    {
        ms = s;
        
        cout << "Child(string s): " << s << endl;
    }
    
    ~Child()
    {
        cout << "~Child() : " << ms << endl;
    }
};

int main()
{
    Child cc("cc");
    
    return 0;
}

        我们来看看编译结果

c++继承中的构造与析构方法是什么

感谢各位的阅读,以上就是“c++继承中的构造与析构方法是什么”的内容了,经过本文的学习后,相信大家对c++继承中的构造与析构方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. 构造方法和析构方法
  2. 构造方法与析构方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++

上一篇:makefile模块独立编译的支持方法是什么

下一篇:c++智能指针怎么用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》