精华内容
下载资源
问答
  • c++ 虚基类

    2019-10-21 20:24:00
    c++ 虚基类 p556

    c++ 虚基类 p556

    展开全文
  • C++虚基类

    万次阅读 2016-02-16 12:35:42
    C++虚基类 1.1虚基类的作用: 如果一个派生类有多个直接基类,而且这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类的多份同名成员。所以为了解决这个问题,C++提供虚基类的方法,使得在...

    C++虚基类

    1.1虚基类的作用:
    如果一个派生类有多个直接基类,而且这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类的多份同名成员。所以为了解决这个问题,C++提供虚基类的方法,使得在继承间接共同基类时只保留一个成员。
    1.2虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的,因为一个基类可以在生成一个派生类时,作为虚基类,在生成另个派生类时,不作为虚基类。
    1.3为了 保证虚基类在派生类中只继承一次,应当在该基类的所有直接基类中声明为虚基类。

    虚基类的初始化

    1.1如果在虚基类中定义了有参数的构造函数,而且没有定义默认构造函数,则在其所有派生类(包括直接和间接)中,通过构造函数的初始化表对虚基类进行初始化。
    1.2在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类进行初始化。
    1.3C++编译系统只执行最后的派生类对虚基类的构造函数的调用,而忽略虚基类的其他派生类(如类B和类C)对虚基类的构造函数的调用,这就保证了虚基类的数据成员不会被多次初始化。
    1.4一段代码:

     #include <iostream>
    
    
    using namespace std;
    
    
    class Person
    {
    public:
        Person(char* n,int a):name(n),age(a){}
    protected:
        char* name;
        int age;
    };
    
    
    class Teacher:virtual public Person
    {
    public:
        Teacher(char* n,int a,char* t):Person(n,a),title(t){}
    protected:
        char* title;
    };
    
    
    class Student:virtual public Person
    {
    public:
        Student(char* n,int a,float sco):Person(n,a),score(sco){}
    protected:
        float score;
    };
    
    
    class Grudate:public Teacher,public Student
    {
    public:
        Grudate(char* n,int a,char* t,float sco,float w):Person(n,a),Student(n,a,sco)
          ,Teacher(n,a,t),wage(w){}
        void show()
        {
            cout << "name: " << name << endl;
            cout << "age: " << age << endl;
            cout << "score: " << score << endl;
            cout << "title: " << title << endl;
            cout << "wage: " << wage << endl;
        }
    private:
        float wage;
    };
    
    
    int main()
    {
        Grudate grud("shukai",20,"good",100,9999);
        grud.show();
        return 0;
    }
    
    
    
    
    1.5在使用多重继承时要十分小心,经常会出现二义性问题,因此许多专业人员认为,不要使用多重继承,能用单一继承解决的问题就不要使用多重继承。

    展开全文
  • C++ 虚基类

    2018-04-03 12:26:28
    教科书上面对C++虚基类的描述玄而又玄,名曰“共享继承”,名曰“各派生类的对象共享基类的的一个拷贝”,其实说白了就是解决多重多级继承造成的二义性问题。例如有基类B,从B派生出C和D,然后类F又同时继承了C和D,...

    教科书上面对C++虚基类的描述玄而又玄,名曰“共享继承”,名曰“各派生类的对象共享基类的的一个拷贝”,其实说白了就是解决多重多级继承造成的二义性问题。例如有基类B,从B派生出C和D,然后类F又同时继承了C和D,现在类F的一个对象里面包含了两个基类B的对象,如果F访问自己的从基类B那里继承过来的的数据成员或者函数成员那么编译器就不知道你指的到底是从C那里继承过来的B对象呢还是从D那里继承过来的B对象。

    于是虚基类诞生了,将C和D的继承方式改为虚继承,那么F访问自己从B那里继承过来的成员就不会有二义性问题了,也就是将F对象里的B对象统一为一个,只有一个基类B对象,下面是一段代码说明了对虚基类的使用。


    #include <iostream>


    using namespace std;


    class A
    {
        public:
        int i;
        void showa(){cout<<"i="<<i<<endl;}
    };


    class B:virtual public A      //此处采用虚继承
    {
        public:
        int j;
    };


    class C:virtual public A      //此处采用虚继承
    {
        public:
        int k;
    };


    class D:public B,public C
    {
        public:
        int m;
    };
    int main()
    {
        A a;
        B b;
        C c;
        a.i=1;
        a.showa();
        b.i=2;
        b.showa();
        c.i=3;
        c.showa();
        D d;
        d.i=4;
        d.showa();
        //cout << "Hello world!" << endl;
        return 0;
    }


    从这个代码我们可以看出B,C,D从A那里继承过来了i这个变量并且它们之间不会有任何影响,如果B和C不是虚继承方式的,那么d.i=4;就不能编译通过了。

    展开全文
  • c++虚基类

    2017-09-03 15:20:58
    在《多继续》中讲过的例子中,由类A,类B1和...假如要想使这个公共基类在派生类中只产生一个基类子对象,则必须将这个基类设定为虚基类。  虚基类的引入和说明  前面简单地介绍了要引进虚基类的原因。实际上,
     在《多继续》中讲过的例子中,由类A,类B1和类B2以及类C组成了类继续的层次结构。在该结构中,类C的对象将包含两个类A的子对象。由于类A是派生类C两条继续路径上的一个公共基类,那么这个公共基类将在派生类的对象中产生多个基类子对象。假如要想使这个公共基类在派生类中只产生一个基类子对象,则必须将这个基类设定为虚基类。

      虚基类的引入和说明

      前面简单地介绍了要引进虚基类的原因。实际上,引进虚基类的真正目的是为了解决二义性问题。

      虚基类说明格式如下:

       virtual <继续方式><基类名>

      其中,virtual是虚类的要害字。虚基类的说明是用在定义派生类时,写在派生类名的后面。例如:

    class A
    {
     public:
      void f();
      PRotected:
      int a;
     };
    class B : virtual public A
    {
      protected:
      int b;
     };
    class C : virtual public A
    {
      protected:
      int c:
     };
    class D : public B, public C
    {
      public:
      int g();
      private:
      int d;
    };

      由于使用了虚基类,使得类A,类B,类C和类D之间关系用DAG图示法表示如下:

    A{ f(), a }
    / \
    B{b} C{c}
    \ /
    D{g(),d}

    从该图中可见不同继续路径的虚基类子对象被合并成为一个对象。这便是虚基类的作用,这样将消除了合并之前可能出现的二义性。这时,在类D的对象中只存在一个类A的对象。因此,下面的引用都是正确的:

      D n;

      n.f(); file://对f()引用是正确的。

     void D::g()

     {
      f(); file://对f()引用是正确的。
     }

      下面程序段是正确的。

      D n;
      A *pa;
      pa = &n;

      其中,pa是指向类A对象的指针,n是类D的一个对象,&n是n对象的地址。pa=&n是让pa指针指向类D的对象,这是正确的,并且也无二义性。 
      虚基类的构造函数

      前面讲过,为了初始化基类的子对象,派生类的构造函数要调用基类的构造函数。对于虚基类来讲,由于派生类的对象中只有一个虚基类子对象。为保证虚基类子对象只被初始化一次,这个虚基类构造函数必须只被调用一次。由于继续结构的层次可能很深,规定将在建立对象时所指定的类称为最派生类。C++规定,虚基类子对象是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的。假如一个派生类有一个直接或间接的虚基类,那么派生类的构造函数的成员初始列表中必须列出对虚基类构造函数的调用。假如未被列出,则表示使用该虚基类的缺省构造函数来初始化派生类对象中的虚基类子对象。

      从虚基类直接或间接继续的派生类中的构造函数的成员初始化列表中都要列出这个虚基类构造函数 的调用。但是,只有用于建立对象的那个最派生类的构造函数调用虚基类的构造函数,而该派生类的基类中所列出的对这个虚基类的构造函数调用在执行中被忽略,这样便保证了对虚基类的对象只初始化一次。

      C++又规定,在一个成员初始化列表中出现对虚基类和非虚基类构造函数的调用,则虚基类的构造函数先于非虚基类的构造函数的执行。

      下面举一例子说明具有虚基类的派生类的构造函数的用法。

    #include 
    class A
    {
    public:
    A(const char *s) { cout<<s<<endl; }
     ~A() {}
    };

    class B : virtual public A
    {
    public:
    B(const char *s1, const char *s2):A(s1)
    {
    cout<<s2<<endl;
     }
    };

    class C : virtual public A
    {
    public:
    C(const char *s1, const char *s2):A(s1)
    {
    cout<<s2<<endl;
     }
    };

    class D : public B, public C
    {
    public:
    D(const char *s1, const char *s2, const char *s3, const char *s4)
    :B(s1, s2), C(s1, s3), A(s1)
    {
    cout<<s4<<endl;
     }
    };

    void main()
    {
    D *ptr = new D("class A", "class B", "class C", "class D");
    delete ptr;
    }

      该程序的输出结果为:

      class A
      class B
      class C
      class D

      在派生类B和C中使用了虚基类,使得建立的D类对象只有一个虚基类子对象。

      在派生类B,C,D的构造函数的成员初始化列表中都包含了对虚基类A的构造函数。

      在建立类D对象时,只有类D的构造函数的成员初始化列表中列出的虚基类构造函数被调用,并且仅调用一次,而类D基类的构造函数的成员初始化列表中列出的虚基类构造函数不被执行。这一点将从该程序的输出结果可以看出。
    展开全文
  • c++ 虚基类和虚函数+代码.有一个案例,里面有源代码。看完就懂什么叫c++ 虚基类和虚函数了
  • If the author of the article is not allowed to reprint, this article will be deleted C++ - 虚基类、虚函数与纯虚函数: ...C++虚基类的实现机制: https://blog.csdn.net/Hsuxu/art...
  • C++虚基类构造函数

    2016-06-14 16:12:06
    C++虚基类构造函数 下面文章详细介绍C++虚基,所谓C++虚基类:是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的,但前提是要深入理解到底什么是C++虚基类,及他是怎么运行的。 前面讲过,为了初始化...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,098
精华内容 3,639
关键字:

c++虚基类

c++ 订阅