美文网首页C++的知识分享程序员C++
10. C++基类和派生类构造函数和析构函数

10. C++基类和派生类构造函数和析构函数

作者: 飞扬code | 来源:发表于2019-04-04 08:12 被阅读17次

    10.1 构造函数

    类的构造函数不能被继承。
    因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。

    在设计派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数完成,但是大部分基类都有 private 属性的成员变量,它们在派生类中无法访问,更不能使用派生类的构造函数来初始化。

    解决这个问题的思路是:在派生类的构造函数中调用基类的构造函数。

    #include<iostream>
    using namespace std;
    
    //基类Person
    class Person{
    protected:
        char *name;
        int age;
    public:
        Person(char*, int);
    };
    Person::Person(char *name, int age): name(name), age(age){}
    
    //派生类Student
    class Student: public Person{
    private:
        float score;
    public:
        Student(char *name, int age, float score);
        void display();
    };
    
    //Person(name, age)就是调用基类的构造函数
    Student::Student(char *name, int age, float score): Person(name, age), score(score){ }
    
    void Student::display(){
        cout<<this->name<<"的年龄是"<<this->age<<",成绩是"<<this->score<<"。"<<endl;
    }
    
    int main(){
        Student stu("呵呵", 18, 78.0);
        stu.display();
        return 0;
    }
    
    image.png

    构造函数调用顺序
    基类构造函数总是被优先调用,这说明创建派生类对象时,会先调用基类构造函数,再调用派生类构造函数,如果继承关系有好多层,例如:
    A --> B --> C
    那么创建 C 类对象时构造函数的执行顺序为:
    A类构造函数 --> B类构造函数 --> C类构造函数

    构造函数的调用顺序是按照继承的层次自顶向下、从基类再到派生类的。
    注意:派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。


    10.2 基类构造函数调用规则

    事实上,通过派生类创建对象时必须要调用基类的构造函数,这是语法规定。
    例如一个失败的例子:

    #include <iostream>
    using namespace std;
    
    //基类Person
    class Person{
    public:
        Person(); //基类默认构造函数
        Person(char *name, int age);
    protected:
        char *name;
        int age;
    };
    
    Person::Person(): name("豆豆"), age(0){ }
    Person::Person(char *name, int age): name(name), age(age){}
    
    //派生类Student
    class Student: public Person{
    public:
        Student();
        Student(char*, int, float);
    public:
        void display();
    private:
        float score;
    };
    
    Student::Student(): score(0.0){ } //派生类默认构造函数
    Student::Student(char *name, int age, float score): Person(name, age), score(score){ }
    
    void Student::display(){
        cout<<this->name<<"的年龄是"<<this->age<<",成绩是"<<this->score<<"。"<<endl;
    }
    
    int main(){
        Student stu1;
        stu1.display();
        Student stu2("哈哈", 16, 80.0);
        stu2.display();
        return 0;
    }
    

    image.png

    10.3 析构函数

    和构造函数类似,析构函数也不能被继承。
    与构造函数不同的是,在派生类的析构函数中不用显式地调用基类的析构函数,
    因为每个类只有一个析构函数,编译器知道如何选择,无需程序员干涉。
    另外析构函数的执行顺序和构造函数的执行顺序也刚好相反:
    1、创建派生类对象时,构造函数的执行顺序和继承顺序相同,即先执行基类构造函数,再执行派生类构造函数。
    2、而销毁派生类对象时,析构函数的执行顺序和继承顺序相反,即先执行派生类析构函数,再执行基类析构函数。

    #include <iostream>
    using namespace std;
    class A{
    public:
        A(){cout<<"A constructor"<<endl;}
        ~A(){cout<<"A destructor"<<endl;}
    };
    class B: public A{
    public:
        B(){cout<<"B constructor"<<endl;}
        ~B(){cout<<"B destructor"<<endl;}
    };
    class C: public B{
    public:
        C(){cout<<"C constructor"<<endl;}
        ~C(){cout<<"C destructor"<<endl;}
    };
    int main(){
        C test;
        return 0;
    }
    
    image.png

    相关文章

      网友评论

        本文标题:10. C++基类和派生类构造函数和析构函数

        本文链接:https://www.haomeiwen.com/subject/mwmxiqtx.html