首页 > 编程语言 >C++_17_多继承和虚基类 - 重写版

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

时间:2023-11-05 23:26:39浏览次数:31  
标签:17 继承 派生类 C++ class int 基类 public

多继承

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

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

//多继承
#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 关键字

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

  这个时候我们引出虚继承和虚基类的概念,使得在派生类(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;
}

 

标签:17,继承,派生类,C++,class,int,基类,public
From: https://www.cnblogs.com/zlxxc/p/17811504.html

相关文章

  • C++_15_友元函数和友元类 - 重写版
    友元函数和友元类友元函数:通过friend关键字,将不属于当前类的函数在当前类中加以声明,使其成为友元函数,同时该函数能够访问private属性的成员变量。友元类:有有元函数,自然也能有友元类,通过friend关键字,将类A在类B中声明,那么类A会成为类B的友元类注意:1、友......
  • C++_14_常量指针—this指针 - 重写版
    常量指针—this指针this指针:成员函数一般都会拥有一个常量指针(this),指向调用函数的对象,储存的是改对象的首地址(注意:静态成员函数是没有this指针的)//标准写法classbook{public:book(){this->price=0.0;this->title=NULL;}private:doubleprice;char......
  • C++_22_string类型 - 重写版
    string类型·变量定义C++中提供了一个string内建数据类型,它可以替代C语言中的char*数组。使用string数据类型时,需要在程序中包含头文件<string>#include<iostream>#include<string>usingnamespacestd;intmain(){strings1;//......
  • C++_21_重载、重写、重定义 - 重写版
    1、重载同一作用域的同名函数,重复定义;参数格式、参数顺序或者参数类型不同;函数重载和函数的返回值没有任何关系;(const类型的重载本质上是参数类型不同) 2、重写(覆盖)有继承关系子类(派生类)重写父类(基类)的虚函数函数的返回值,函数名字,函数参数,必须和基类中的虚函数一致,主要就是覆盖......
  • C++_20_操作符重载和函数重载 - 重写版
    操作符(运算符)重载 操作符重载指的是将C++提供的操作符进行重新定义或者多重定义,使之满足我们所需要的一些功能。在C++中,经常有需要对多个对象进行算术运算,但是对象比不是基本的数据类型,所以这些运算符都无法执行。为了让程序识别这些运算符,就需要对运算符进行重载......
  • C++_19_虚函数、纯虚函数和抽象类 - 重写版
    虚(成员)函数:在C++中,只有类中的成员函数能被声明为虚函数,顶层函数则不能被声明为虚函数;并且如果在类内声明类外定义,则只在类内声明时加virtual声明虚函数是为了构成多态,多态需要继承关系,需要在类中声明;虚函数能被继承:基类被声明为虚函数,那么派生类即便未添......
  • C++_25_函数模板和类模板 - 重写版
    模板:在C++中允许函数重载,但函数重载每次都必须完全对上参数的顺序,类型和数量。所以C++提供了另一种代码重用机制——“模板”,可以作为同一种类型函数的统一调用接口。模板机制下可划分:1、函数模板      2、类模板模板的语......
  • C++_28_空指针、野指针、智能指针 - 重写版
     野指针:没有明确执向的指针,可能会胡乱指向任意一个变量;编程的时候绝不允许出现野指针;int*p;//错误,未初始化指向一块地址,会变成野指针如果确实需要先不指定到需要使用的内存,那就先定义一个空指针;-------》宁愿指向为空也不要为野;因为野指针你把握不住; 空指针:让指针指向N......
  • C++_02_命名空间和作用域运算符 - 重写版
    命名空间在C++中命名空间(namespace)的作用:命名空间,就是为了解决同一个源代码中相同命名的变量或者函数之间相互冲突的问题,就是要避免这种冲突,让程序代码中可以多次使用同一个标识符而存在的。对于一名开发者而言,代码量过于庞大,或多或少会忘记之间之前用过的变量名或函......
  • C++_01_初步认识C++语言 - 重写版
    一、认识“C++语言”一、首先聊聊什么是语言?语言是一套具有“语法”、“词法”规律的系统,是思维的工具。计算程序设计语言是计算机可以识别的语言,用于描述解决问题的方法,供计算机阅读和执行。语言由低级到高级依次分为4类:1、机器语言     (由......