继承与派生

继承与派生

继承:一旦指定了某种事物的父代的本质特征,那么它的子代将会自动具有那些性质,这就是一种朴素的可重用的概念。
派生: 子代可以拥有父代没有的特性,这就是可扩充的概念
继承就是在已经存在的基础上建立一个新的类,已存在的类称为基类或父类, 新建立的类称为派生类或子类。

派生类的功能:

1、吸收基类成员
2、改造基类成员
3、添加新成员

单继承和多继承

单继承: 派生类只有一个直接基类。
语法格式:class 派生类名:<继承方式> 基类名{
…//派生类修改基类成员
…//派生类添加新成员
};
由继承方式的不同而导致的继承成员访问属性的改变
基类:          公有成员 私有成员    保护成员
公有派生类:公有成员 不可访问成员 保护成员
私有派生类:私有成员 不可访问成员 私有成员
保护派生类:保护成员 不可访问成员 保护成员

不可访问成员 :在类外不能被直接访问,在派生类的类内不能被直接访问。

派生类与基类同名成员的访问方式:
c++允许派生类可以重新定义基类成员,此时称派生类成员覆盖了基类的同名成员。
如果在派生类中,想使用基类的同名成员,则可以显式地使用用类名+限定符的方式:
基类名::成员名

单继承派生类的构造函数

派生类构造函数(参数表):基类构造函数(参数表),对象成员1(参数表),…对象成员函数n(参数表),{…//初始化自定义数据成员}

class Circle{
            Point center;
            float radius;
            ......
 public
           Circle(float x,float y,float r):center(x,y)
            {
                radius=r;
            }
    }
class ColorCircle:public Circle{ 
      int color;
public:
     ColorCircle(float x,float y,float r,int color):Circle(x,y,z){
     this->color=color;
}

如果基类使用的是缺省的构造函数或不带参数的构造函数,那么在初始化列表中可以省略:基类构造函数这已项,对象成员参数列表同理。

构造函数和析构函数的调用顺序
构造函数: 1、调用基类构造函数 2、再调用对象成员所属类的构造函数 3、最后调用派生类构造函数;

析构函数:1、先调用派生类析构函数 2、再调用对象成员析构函数 3、最后调用基类构造函数。恰好与构造函数的调用相反。

class Base{
public:
      Base(){cout<<"Base obj created"<<endl;}
      ~Base(){cout<<"Base obj deleted"<<endl;}
     };
     class Derived:public Base{
     public:
            Derived(){cout<<"Derived obj created"<<endl;}
            ~Derived(){cout<<"Dericed obj deleted"<<endl;}
         }int main(){
     Derived d;
     return 0;
//则其结果的输出是什么呢?先调用了基类的构造函数,输出Base obj created;
//再调用对象成员函数,此处没有,然后调用派生类构造函数输出:Derived obj created;
//之后调用析构函数,实现顺序与之相反,因此会输出:Derived obj deleted  Base obj deleted;
   

多继承 派生类有多个直接基类
定义多继承派生类语法格式
class 派生类名 :<继承方式>基类名1,<继承方式>基类名2,…
{
…//派生类新添加的成员
};
多继承派生类构造函数,和析构函数的执行顺序与单继承派生类一致。
   多继承存在一个问题,当访问不同基类的同名成员时,会存在二义性。
解决办法:用类名对成员进行加以限定,列如:
C1.A::f();或者C1.B::f();其中C1时、是派生类名,A和B则是基类名,::命名空间,f()是基类中的成员。
访问共同基类成员的二义性:当一个派生类对象是由两个基类成员派生而来。并且两个基类成元是由同一个派生类对象派生来时,此时如果我们想要访问最初的那个基类函数的成员1时,也会出现二义。
解决办法: Cobj.B1::a=9或Cobj.B2::a=9;
其中Cobj是派生类对象,B1是派生类的基类对象,a是B1内多成员函数。其实质访问的是派生类的基类的基类内部成员。

虚基类
A
B
C
D

类A是派生类D两条继承路径上的一个公共基类,
因此这个公共基类会在派生类对象中产生两个基类子对象,虽然可以通过限定符的方式避免二义性,但如果我们不需要在派生类对象中存在多个基类对象的拷贝。因此如果要使在公共基类在派生类中只产生一个基类子对象,则需要将这个基类设置为虚基类。+virtual。

class base{...};
class base2{...};
class level1:public base2,virtual public base{...};
class level2:public base2,virtual public base{...};
class toplevel:public level1,virtual public level2{...};
//当声明toplevel类的对象时,构造函数的调用次序为:
//base base2 level2 base2 level1 toplevel;
//虚构函数首先调用,并且只调用一次。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值