zoukankan      html  css  js  c++  java
  • c++ 虚基类应用

    多重继承存在二义性,为了消除二义性在访问相同名称的属性时需要加上类名,加以区分。虽然这样可以解决二义性,但是相同的属性出现在多个基类中,为了解决数据冗余,c++引入了虚基类。

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

      初始化

    /*
    如果在虚基类中定义了带参数的构造函数,而且没
    有定义默认构造函数,则在其所有派生类(包括直
    接派生或间接派生的派生类)中,通过构造函数的
    初始化表对虚基类进行初始化。例如*/
    class A//定义基类A
     {A(int i){ }                         //基类构造函数,有一个参数
    …};
    class B :virtual public A           //A作为B的虚基类
     {B(int n):A(n){ }                   //B类构造函数,在初始化表中对虚基类初始化
    …};
    class C :virtual public A           //A作为C的虚基类
     {C(int n):A(n){ }                   //C类构造函数,在初始化表中对虚基类初始化
    …};
    class D :public B,public C     //类D的构造函数,在初始化表中对所有基类初始化
     {D(int n):A(n),B(n),C(n){ }
    …};
    /*
    注意: 在定义类D的构造函数时,与以往使用的方法有所不同。规定: 在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化。
    
    C++编译系统只执行最后的派生类对虚基类的构造函数的调用,而忽略虚基类的其他派生类(如类B和类C) 对虚基类的构造函数的调用,这就保证了虚基类的数据成员不会被多次初始化。
    */

    应用实例:

      

    #include  "stdafx.h"
    #include <iostream>
    #include <string>
    using namespace std;
    //声明公共基类Person
    class Person
    {
    public:
        Person(string nam,char s,int a)//构造函数
        {
            name=nam;
            sex=s;
            age=a;
        }
    protected:                                        //保护成员
       string name;
       char sex;
       int age;
    };
    //声明Person的直接派生类Teacher
    class Teacher:virtual public Person                //声明Person为公用继承的虚
    {
    public:                                 
       Teacher(string nam,char s,int a, string t):Person(nam,s,a)//构造函数
        {
           title=t; 
        }
    protected:                                       //保护成员
        string title;                                //职称
    };
    //声明Person的直接派生类Student
    class Student:virtual public Person               //声明Person为公用继承的虚基类
    {
    public:
        Student(string nam,char s,int a,float sco)      //构造函数
          :Person(nam,s,a),score(sco){ }                //初始化列表
    protected:                                          //保护成员
        float score;                                    //成绩
     };
    //声明多重继承的派生类Graduate
    class Graduate:public Teacher,public Student   //Teacher和Student为直接基类
    {
    public:
        Graduate(string nam,char s,int a, string t,float sco,float w)            //构造函数
            :Person(nam,s,a),Teacher(nam,s,a,t),Student(nam,s,a,sco),wage(w){}    //初始化表
        void show( )                                                            //输出研究生的有关数据
        {    
            cout<<"name:"<<name<<endl;
            cout<<"age:"<<age<<endl;
            cout<<"sex:"<<sex<<endl;
            cout<<"score:"<<score<<endl;
            cout<<"title:"<<title<<endl;
            cout<<"wages:"<<wage<<endl;
        }
    private:
        float wage;                     //工资
     };
    //主函数 
    int main(int argc,char* argv[])
    {
        Graduate grad1("Wang-li",'f',24,"assistant",89.5,1234.5); 
        grad1.show();
        return 0;
    }
    /*
    不要提倡在程序中使用多重继承,只有在比较简单和不易出现二义性的情况或实在必要时才使用多重继承,能用单
    一继承解决的问题就不要使用多重继承。也是由于这个原因,有些面向对象的程序设计语言(如Java,Smalltalk)并不支持多重继承。
    */
  • 相关阅读:
    manjora20安装搜狗输入法
    manjora20使用体验
    deepin20体验
    deepin20搜狗输入法使用
    deepin20使用snap并设置代理
    C#服务器端使用office组件
    华为多屏互动看学英语
    ThinkPad S5立体声混响以及语音识别
    mate10碎屏机当成小电脑使用尝试
    刷机错误ERROR:STATUS_BROM_CMD__FAIL
  • 原文地址:https://www.cnblogs.com/lbangel/p/3274887.html
Copyright © 2011-2022 走看看