四.继承总结

继承,是在已有类基础上创建新类的过程。

使用继承可以减少代码量,提高效率。

1.以一个例子为例:

#include<bits/stdc++.h>
using namespace std;
class side//创建边类
{
protected://需要把数据成员规定为保护类或公有类才可以使用继承,一般为保护类;
    int length,width;//定义边的长宽
public:
    void inputLW(){cout<<"please intputLW:";cin>>length>>width;}
    void outputLW(){cout<<"this is LW: "<<length<<" "<<width<<endl;}
};

class area:public side
/*
面积类继承边类;
称面积类为子类或派生类
称边类为父类或基类
格式:   class area:public side
声明为共有继承,但无论何种继承,派生类都不能直接调用基类数据成员
*/
{
protected :
    int s;
public:
    void sets()
    {
        side::inputLW();
        //派生类吸收了基类成员(除构造函数析构函数外)
    }
    void outputLW()
    {
        side::outputLW();
        //派生类改造了基类函数
        //虽然两者同名,但是使用此种格式可对基类改造;
        cout<<length*width<<endl;
    }
    void prints()
    {
      s=length*width;
      cout<<s<<endl;
      /*在派生类中添加新成员,确保自己功能的实现;
      此处,例如基类中含有长度宽度两个数据成员,在派生类中又定义了一个新成员面积。故派生类中现在有三个数据成员;
      */
    }
};
int main()
{
    area a;
    a.sets();
    a.outputLW();
    //a.side::outputLW();
    a.prints();

}

2.如果继承和派生类中有重名函数或数据成员,在派生类中访问同名成员时hide了基类的同名成员,若还想继续用基类成员,需要使用类名限制符::

四.继承总结

例如上例子,基类和派生类中函数名称相同,若还想用基类的函数outputLW,就要用类名限制符,使用side::outputLW()来调用基类的同名函数;

3.静态数据成员与基类和派生类

基类的静态数据成员为所有派生类(此基类加派生类)共享;

派生类中访问静态成员,用以下形式显式说明:

类名 :: 成员或通过对象访问  对象名 . 成员;

例如:

class base
{
protected:
    static int i;
public:
    static void add()
    {
        ++i;
    }
    void print()
    {
        cout<<"this is i:"<<i<<endl;
    }
};
int base::i=0;
class derive:public base
{
public:
    void operate()
    {
        i=5;
        i++;//变为6
        print();
        add();//7
        base::i++;//8
        base::add();//9
        print();
    }
};
int main()
{
    derive d;
    d.operate();
}

4.构造函数

执行顺序  基类->对象成员->派生类;

class  parent_class

{     int data1 , data2 ;

   public :

       parent_class ( int  p1 , int p2 ) { data1 = p1; data2 = p2; }

};

class  derived_class : private  parent_class//这个类继承上一个类

{     int data3 ;

      parent_class data4 ;//对象成员

   public:

       derived_class ( int  p1 , int p2 , int  p3 , int p4 , int  p5 ): parent_class ( p1 , p2 ) , data4( p3 , p4 )

           { data3 = p5 ; }

//先把基类初始化,再初始化对象成员,再利用变元表初始化其他数据

};

要注意:

1.基类的构造函数和析构函数能被继承
2.如果基类没有定义构造函数有无参的构造函数, 派生类也可以不用定义构造函数
3.如果基类无参的构造函数,派生类必须定义构造函数
//例如上一个类的基类有 有参的构造函数,则派生类必须定义构造函数;

//利用派生类构造函数初始化基类数据成员

4.如果派生类的基类也是派生类,则每个派生类只负责直接基类的构造

5.派生类是否定义析构函数与所属的基类无关

5.析构函数

执行顺序为派生类的析构函数→对象成员的析构函数→基类的析构函数。

6.赋值兼容规则

指的是想使用基类对象的时候都可以用公有派生类对象来代替

可以有以下三种情况

a派生类的对象可以赋给基类对象//但要注意基类对象不可以赋值给派生类对象

b 派生类的对象可以初始化基类的引用//反之不行

c 派生类的对象的地址可以赋给基类类型的指针//反之不行

派生类拥有基类所有功能;

base a;

derive b;

a=b;

base &br=b;

base *p=&b;//把派生类地址赋值给基类

替代之后,派生类对象就可以作为基类的对象使用,但只能使用从基类继承的成员。