C++ 虚基类
C++ 虛基類
- 概述
- 多重繼承的問題
- 虛基類
- 初始化
- 例子
- 總結
概述
虛基類 (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_HStudent 類:
#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_HTeacher 類:
#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_HGraduate 類:
#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_Hmain:
#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++ 虚函数