C++程序笔记——继承和多态程序实例

C++程序笔记——继承和多态程序实例

派生类构造函数和析构函数程序实例

知识点

  • 构造函数和析构函数调用顺序

    • 当创建派生类对象时,先调用基类的构造函数,在调用派生类的构造函数
    • 析构函数的调用顺序总是和构造函数的调用顺序相反
  • 派生类构造函数的声明方法
    <派生类类名>(形参列表):<基类类名>(基类初始化的形参列表)
    在这里插入图片描述

C++实现代码

person.h文件

#include <iostream>
#include <string.h>

using namespace std;

#ifndef _PERSON_H_
#define _PERSON_H_

class Person
{
    
    
private:
    char m_name[20];
    bool m_sex;
    //true representing male, false representing female
public:
    Person(char *name,bool sex)
    {
    
    
        strcpy(m_name,name);
        m_sex = sex;
        cout<<"Person is constructing"<<endl;
    }
    ~Person(){
    
    cout<<"Person is deleting"<<endl;}
};
#endif // _PERSON_H_

Student.h文件

#include "Person.h"
#include <iostream>
#include <string.h>

using namespace std;

class Student1:public Person
{
    
    
private:
    char m_sno[8];
    char m_major[20];
public:
    Student1(char *sno,char *major,char *name,bool sex):Person(name,sex)
    {
    
    
        strcpy(m_sno,sno);
        strcpy(m_major,major);
        cout<<"the object of student is constructing"<<endl;
    }
    ~Student1()
    {
    
    
        cout<<"Student is deleting"<<endl;
    }
};

测试的main函数

#include <iostream>
#include "Student1.h"
#include "Person.h"

using namespace std;

int main()
{
    
    
    Student1 stu("16082022","computer science and technology","gray",true);
    return 0;
}

效果图

在这里插入图片描述

函数重定义和派生类的继承方式的实例

知识点

  • 关于方法重定义,父类和子类的方法名称,返回类型,和参数列表要完全相同

编写运行的样例

  • 父类的方法
    在这里插入图片描述

  • 子类重定义后
    在这里插入图片描述

  • 测试函数

在这里插入图片描述

  • 实验结果
    在这里插入图片描述

分析与总结

  • 父类调用重定义后的方法,是父类的原来的方法,子类调用,就是子类重定义之后的方法
  • 主要是公有继承,都能访问父类的私有成员和方法,其余都可。

在这里插入图片描述

多重继承下的派生类定义

知识点

  • 使用方法

在这里插入图片描述

  • 在创建通过多重继承定义的派生类对象时,会先调用基类的构造函数,在调用派生类的构造函数,调用顺序和多重继承的顺序一致
  • 析构函数的调用顺序总是与构造函数的调用顺序相反

C++代码实现

类体说明

在这里插入图片描述

代码
  • Person.h文件
#include <iostream>
#include <string.h>

using namespace std;

#ifndef _PERSON_H_
#define _PERSON_H_

class Person
{
    
    
private:
    char m_name[20];
    bool m_sex;
    //true representing male, false representing female

public:
    Person(char *name,bool sex)
    {
    
    
        strcpy(m_name,name);
        m_sex = sex;
        cout<<"Person is constructing"<<endl<<endl;
    }
    ~Person(){
    
    cout<<"Person is deleting"<<endl;}
    char *getName(){
    
    return m_name;}
    bool getSex(){
    
    return m_sex;}
    void SetName(char *name){
    
    strcpy(m_name,name);}
    void displayInfo()
    {
    
    
        cout<<"the function of father"<<endl;
        cout<<"name:"<<m_name<<endl;
        cout<<"sex:"<<m_sex<<endl;
        cout<<endl;
    }
};
#endif // _PERSON_H_
  • Student1.h文件
#include "Person.h"
#include <iostream>
#include <string.h>

using namespace std;

class Student1:public Person
{
    
    
private:
    char m_sno[8];
    char m_major[20];
public:
    Student1(char *sno,char *major,char *name,bool sex):Person(name,sex)
    {
    
    
        strcpy(m_sno,sno);
        strcpy(m_major,major);
        cout<<"the object of student is constructing"<<endl<<endl;
    }
    ~Student1()
    {
    
    
        cout<<"Student is deleting"<<endl;
    }
    void setSNO(char *sno){
    
    strcpy(m_sno,sno);}
    char *getSNO(){
    
    return m_sno;}
    void setMajor(char *major){
    
    strcpy(m_major,major);}
    char *getMajor(){
    
    return m_major;}
    void displayInfo()
    {
    
    
        cout<<"the function of children"<<endl;
        cout<<"name:"<<getName()<<endl;
        cout<<"sex:"<<getSex()<<endl;
        cout<<"no:"<<m_sno<<endl;
        cout<<"major:"<<m_major<<endl;
        cout<<endl;
    }
};
  • Teacher.h文件
#include "Person.h"
#include <iostream>

using namespace std;

class Teacher:public Person
{
    
    
private:
    char m_tno[6];
    char m_depart[20];
public:
    Teacher(char *name,bool sex,char *tno,char *depart):Person(name,sex)
    {
    
    
        strcpy(m_tno,tno);
        strcpy(m_depart,depart);
        cout<<"the constructor is being used!!"<<endl;
    }
    ~Teacher(){
    
    cout<<"the destructor of teacher is being used!!"<<endl;}
    void setTno(char *tno){
    
    strcpy(m_tno,tno);}
    char *getTno(){
    
    return m_tno;}
    void setDepart(char *depart){
    
    strcpy(m_depart,depart);}
    char *getDepart(){
    
    return m_depart;}
};
  • TA.h文件
#include "Student1.h"
#include "Teacher.h"
#include <iostream>

using namespace std;

class TA:public Student1,public Teacher
{
    
    
public:
    TA(char *tno,char *name,char *sno,char *major,char *depart,bool sex)
        :Teacher(name,sex,tno,depart),Student1(sno,major,name,sex)
    {
    
    
        cout<<"the constructor of TA is being used!!"<<endl;
    }
    ~TA(){
    
    cout<<"the destructor of TA is being used!!"<<endl;}
};
  • 测试文件
#include <iostream>
#include "TA.h"

using namespace std;

int main()
{
    
    
    TA ta("1210102","gray","11111111","computer science and technology"
          ,"software programming",true);
    return 0;
}

分析与总结

  • 不得不说,C++的派生类的声明和初始化着实很费劲,还要和父类初始化的参数列表顺序一致,而且相同参数要写两遍,致使一行句子可以写的长出天际
  • 不要重复引入文件,只需要引入最底下的派生类即可,因为在其基类的文件中已经引入了对应的基类所在的文件

多重继承中的二义性问题

在这里插入图片描述
在这里插入图片描述

  • TA分别继承了Teacher类和Student类,而二者又各自继承了Person类,如果通过TA调用Person类就会发生编译错误,因为系统不知道调用哪个类的Person类成员
解决办法
  • 指定特定的父类都调用父类的父类,减少二义性的出现
    在这里插入图片描述
  • 使用虚拟继承和虚拟基类

使用虚拟继承和虚拟基类

针对问题

解决类的多重继承中的二义性

声明方式

定义
在这里插入图片描述
在这里插入图片描述

初始化
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Blackoutdragon/article/details/108834953