C++_17_多继承和虚函数、虚基类 - 重写版

多继承

  单继承:一个派生类只有一个基类,这就是单基类继承,简称“单继承”
  多继承:一个派生类允许有两个及以上的基类,这就是多基类继承,简称“多继承”
  单继承中,派生类是对基类的特例化,例如编程类书籍是书籍中的特例。而多继承中,派生类是所有基类的一种组合。
  在多继承中,派生类继承了所有基类中的所有成员变量和成员函数,这些继承过来的成员变量及成员函数其访问规则与单继承是相同的

  使用多继承可以描述事物之间的组合关系,但是如此一来也可能会增加命名冲突的可能性,冲突可能很有可能发生在基类与基类之间,基类与派生类之间。为了解决命名冲突问题我们只能采用域解析操作符来区分具体所调用的类中的成员函数。

//多继承
#include<iostream>
using namespace std;
class A { public: int a; int b; }; class B { public: int a; int c; }; class C : public A ,public B { }; void test_25() { C csd; csd.A::a = 100; csd.B::a = 200; //cout << csd.a << endl; //err 指向不明确 //做好作用域区分就好 cout << csd.A::a << endl; //100 cout << csd.B::a << endl; //200 } int main() { test_25(); return 0; }

 

 

虚函数 和 纯虚函数

        虚函数:在类中函数前加上 virtual 关键字,父类的虚函数可以在子类中被重写(override),即重新实现,但是参数和返回值必须保持一致!

//父类
class Human{
    public:
        virtual void say(){     //父类定于虚函数
            cout<<"I'm human"<<endl;
        }
};

//子类
class student:public Human{
    public:
        void say(){     //子类重写父类的虚函数
            cout<<"I'm a student"<<endl;
        }
};

 

       纯虚函数:不实现,仅申明为纯虚函数,留待子类里面重写定义!

class Shape{
    public:
        //父类中只声明,不定义;留待子类重写定义的虚函数 -- 叫纯虚函数
        //写法就是声明函数直接赋值为 0
        virtual float get() = 0; 
        virtual float push() = 0;
        
};

 

       含有纯虚函数的类叫做抽象类。因为存在不明确、比较抽象的函数嘛!
       仅仅只含有纯虚函数的类叫做接口,因为完全不做任何实际定义嘛!

 

虚继承和虚基类

  虚继承:在继承属性前加上 virtual 关键字

  在多继承时很容易产生命名冲突问题,如果我们很小心地将所有类中的成员变量及成员函数都命名为不同的名字时,命名冲突依然有可能发生,比如非常经典的菱形继承结构。

  这个时候我们引出虚继承和虚基类的概念,使得在派生类(D类中只保留一份间接基类(A类)成员

class A
{
public:
    void setx(int a){x = a;}
    int getx(){return x;}
private:
    int x;
};
class B: virtual public A          //B类虚继承于A类
{
public:
    void sety(int a){y = a;}
    int gety(){return y;}
private:
    int y;   
};
class C: virtual public A         //C类也虚继承于A类
{
public:
    void setz(int a){z = a;}
    int getz(){return z;}
private:
    int z;
};
class D: public B, public C
{
    //......
};


//B类和C类都虚继承于A类,这样就导致继承于B类和C类的D类只会获得A类中相同数据的一份,
//而不是两份,避免命名冲突和语病 //因为虚继承让B类和C类在合成D类时具备悬着性,异实同虚

 

   虚继承的目的是让某个类做出声明,承诺愿意共享它的基类。
        其中,这个被共享的基类就称为虚基类(Virtual Base Class),本例中的 A 就是一个虚基类。
        在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员。虚派生只影响从指定了虚基类(A类)的派生类中进一步派生出来的类(D类),它不会影响派生类本身(B类和C类)。

//菱形继承
#include<iostream>
#include<string.h>
using namespace std;

class Animal
{
public:
    int data;
};

class Sheep :virtual public Animal
{
public:
};
class Tuo :virtual public Animal
{
public:
};

class SheepTuo :public Sheep, public Tuo
{
public:
};


int main(int argc, char* argv[])
{
    SheepTuo st;
    st.data = 200; //SheepTuo 不会再从 Animal 获取多个 data了
    cout << st.data << endl; //200
    return 0;
}

 

posted @ 2023-12-03 23:59  尘落曦枫  阅读(112)  评论(0)    收藏  举报