C/C++中虚基类详解及其作用介绍

编辑: admin 分类: c#语言 发布时间: 2021-12-12 来源:互联网
目录
  • 概述
  • 多重继承的问题
  • 虚基类
    • 初始化
    • 例子
  • 总结

    概述

    虚基类 (virtual base class) 是用关键字 virtual 声明继承的父类.

    在这里插入图片描述

    多重继承的问题

    N 类:

    class N {
    public:
        int a;
        void display(){
            cout << "A::a=" << a <<endl;
        }
    };
    

    A 类:

    class A : public N {
    public:
        int a1;
    };
    

    B 类:

    class B : public N {
    public:
        int a2;
    };
    

    C 类:

    class C: public A, public B{
    public:
        int a3;
        void display() {cout << "a3=" << a3 << endl;};
    };
    

    main:

    int main() {
        C c1;
        // 合法访问
        c1.A::a = 3;
        c1.A::display();
    
        return 0;
    }
    

    输出结果:

    A::a=3

    存在的问题:

    • A::a 和 B::a 是 N 类成员的拷贝
    • A::a 和 B::a 占用不同的空间

    在这里插入图片描述

    虚基类

    我们希望继承间接共同基类时只保留一份成员, 所以虚基类就诞生了. 当基类通过多条派生路径被一个派生类继承时, 该派生类只继承该基类一次.

    语法:

    class 派生类名: virtual 继承方式 基类名
    

    初始化

    通过构造函数的初始化表对虚拟类进行初始化. 例如:

    N 类:

    class N {
    public:
        int n;
        N(int n) : n(n) {};
    };
    

    A 类:

    class A : virtual public N {
    public:
        A(int n) : N(n) {};
    };
    

    B 类:

    class B : virtual public N {
    public:
        B(int n) : N(n) {};
    };
    

    C 类:

    class C: public A, public B{
    public:
        C(int n) : N(n), A(n), B(n){};
    };
    

    例子

    Person 类:

    #ifndef PROJECT5_PERSON_H
    #define PROJECT5_PERSON_H
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Person {
    protected:
        string name;
        char gender;
    public:
        Person(string n, char g) : name(n), gender(g) {}
        void display() {
            cout << "name: " << name << endl;
            cout << "gender: " << gender << endl;
        }
    };
    
    #endif //PROJECT5_PERSON_H
    

    Student 类:

    #ifndef PROJECT5_STUDENT_H
    #define PROJECT5_STUDENT_H
    
    #include <string>
    #include "Person.h"
    using namespace std;
    
    class Student : virtual public Person {
    protected:
        double score;
    public:
        Student(string n, char g, double s) : Person(n, g), score(s) {};
    };
    
    #endif //PROJECT5_STUDENT_H
    

    Teacher 类:

    #ifndef PROJECT5_TEACHER_H
    #define PROJECT5_TEACHER_H
    
    #include <string>
    #include "Person.h"
    using namespace std;
    
    class Teacher : virtual public Person {
    protected:
        string title;
    public:
        Teacher(string n, char g, string t) : Person(n, g), title(t) {};
    };
    
    #endif //PROJECT5_TEACHER_H
    

    Graduate 类:

    #ifndef PROJECT5_GRADUATE_H
    #define PROJECT5_GRADUATE_H
    
    #include "Teacher.h"
    #include "Student.h"
    #include <string>
    using namespace std;
    
    class Graduate : public Teacher, public Student{
    private:
        double wage;
    public:
        Graduate(string n, char g, double s, string t, double w) : Person(n, g), Student(n, g, s), Teacher(n, g, t), wage(w) {};
        void display() {
            Person::display();
            cout << "score: " << score << endl;
            cout << "title: " << title << endl;
            cout << "wages: " << wage << endl;
        };
    };
    
    #endif //PROJECT5_GRADUATE_H
    

    main:

    #include <iostream>
    #include "Graduate.h"
    using namespace std;
    
    int main() {
        Graduate grad1("小白",'f',89.5,"教授",1234.5);
        grad1.display();
    
        return 0;
    }
    

    输出结果:

    name: 小白
    gender: f
    score: 89.5
    title: 教授
    wages: 1234.5

    总结

    • 使用多重继承时要十分小心, 否则会进场出现二义性问题
    • 不提倡在程序中使用多重继承
    • 只有在比较简单和不易出现二义性的情况或实在必要时才使用多重继承
    • 能用单一继承解决的问题就不要使用多重继承

    在这里插入图片描述

    到此这篇关于C/C++中虚基类详解及其作用介绍的文章就介绍到这了,更多相关C++虚基类内容请搜索海外IDC网以前的文章或继续浏览下面的相关文章希望大家以后多多支持海外IDC网!

    【文章出处:台湾服务器 转载请保留连接】