C++新特性(继承*****五颗星)

来源:互联网 发布:差热分析实验数据分析 编辑:程序博客网 时间:2024/06/06 16:48

继承:一个类直接包含另一个类的属性和方法。

同类事物具有共同性,在同类事物中,每个事物又具有特殊性。运用抽象的原则舍弃对象的特殊性,抽取其共同性,则得到一个适应于一批对象的类,这就是基类(父类);

把具有特殊性的类称为派生类(子类)。派生类的对象拥有基类的全部或部分属性与方法,称作派生类对基类的继承。

 

继承的方式有三种:公有继承,私有继承和保护继承

通过一个列子,体会不同的继承方式对类的成员函数的影响:

class CFruit          //声明基类{    public:        void func1(); //成员函数    protected:        int x1;         //保护数据成员    private:        int y1;         //私有数据成员};class CApple:public CFruit          //CApple类公共继承于CFruit类{    public:        void func2(); //成员函数    protected:        int x2;         //保护数据成员    private:        int y2;         //私有数据成员};class COrange:private CFruit          //COrange类私有继承于CFruit类{    public:        void func3(); //成员函数};class CRichApple:public CApple//CRichApple类公共继承于CApple类{    public:        void func4(); //成员函数};class CGrapefruit:public COrange//CGranpefruit类共有继承于COrange类{    public:        void func5(); };

1、子类CApple中的成员函数func2,可以访问父类CFruit中的成员函数func1和数据成员x1,而不能访问数据成员y1;

2、子类COrange中的成员函数func3,和第一条相同;

3、子类CRichApple中的成员函数func4,可以访问CFruit中的成员函数func1,和CApple中的成员函数func2和数据成员x2,但不能访问CFruit的数据成员x1和y1和CApple的数据成员y2;

4,子类CGrapefruit中的成员函数func5,不能访问CFruit中的任何成员,但可以访问COrange中的成员函数func3.

 

子类的构造函数:

要实现子类的构造函数,除了对子类自己的数据成员进行初始化,还必须负责调用父类的构造函数来使父类的数据成员得到初始化。初始化父类的数据成员,必须采用初始化成员列表的方式进行,如果子类中还有子对象,则还应包含子对象的初始化。

子类构造函数的调用顺序为 先调用父类构造函数,再调用子类构造函数

通过一个程序例子来体会:

#include <iostream>#include <fstream>using namespace std;class CPoint{    public:        CPoint();        CPoint(int x,int y);        void disp();        void getXY(int &x,int &y);    private:        int m_x;        int m_y;};CPoint::CPoint(){    m_x=0;    m_y=0;    cout<<"调用CPoint的默认构造函数"<<endl;}CPoint::CPoint(int x,int y){    m_x=x;    m_y=y;    cout<<"调用CPoint的构造函数"<<endl;}void CPoint::getXY(int &x,int &y){    x=m_x;    y=m_y;}void CPoint::disp(){    cout<<m_x<<","<<m_y<<endl;}class C3DPoint:public CPoint  //声明子类C3DPoint继承于CPoint类{    public:        C3DPoint();        C3DPoint(int x,int y,int z);        void disp();    private:        CPoint p;        int m_z;};C3DPoint::C3DPoint():CPoint() //调用父类的默认构造函数{    m_z=0;    cout<<"调用C3CPoint默认构造函数"<<endl;}C3DPoint::C3DPoint(int x,int y,int z):CPoint(x,y),p(x,y)//(使用初始化成员列表的方式)调用父类的构造函数,并初始化子对象{    m_z=z;    cout<<"调用C3CPoint构造函数"<<endl;}void C3DPoint::disp(){    int x=0,y=0;    p.getXY(x,y);    cout<<x<<","<<y<<","<<m_z<<endl;}int main(){    C3DPoint point3d1,point3d2(50,80,10);    CPoint p(20,30);    p.disp();    point3d1.disp();    point3d2.disp();    return 0;}

从代码的输出结构可以看出,子类的对象point3d不仅可以实现父类对象p的全部功能,而且还增加了新的功能,实现了z轴坐标的输出。

 

子类的析构函数,调用过程是:先调用子类的析构函数,再调用父类的析构函数。

 

子类的类型适应:

基类对象的指针和引用可以代表派生类对象的指针和引用。但是子类的指针和引用并不能代表父类的对象指针和引用,否则会产生编译错误。

 

多继承:

一个子类对多个父类的关系:

例子:多继承的子类构造函数示例:

 

#include <iostream>#include <fstream>using namespace std;class CAnimal{    public:        CAnimal(){m_age=0;}        CAnimal(int age);        void disp();    private:        int m_age;};CAnimal::CAnimal(int age){    m_age=age;    cout<<"调用CAnimal的构造函数"<<endl;}void CAnimal::disp(){    cout<<m_age<<",";}class CMammal{    public:        CMammal(){m_latex=0;}        CMammal(int latex);        int getNum(){return m_latex;}        void disp();    private:        int m_latex;};CMammal::CMammal(int latex){    m_latex=latex;     cout<<"调用CMammal的构造函数"<<endl;}void CMammal::disp(){    cout<<m_latex<<",";}  class CMonkey:public CAnimal,public CMammal //共有多继承于CAnimal和CMammal{    public:        CMonkey(int age,int latex,int a,int tail);        void print();    private:        CMammal mammal;        int m_tail;};CMonkey::CMonkey(int age,int latex,int a,int tail):CMammal(latex),CAnimal(age),mammal(a)  //类CMonkey构造函数,多继承的子类构造函数中,必须通过初始化成员列表调用多个父类的构造函数{    m_tail=tail;    cout<<"调用CMonkey的构造函数"<<endl;}void CMonkey::print(){    CAnimal::disp();    CMammal::disp();    cout<<mammal.getNum()<<","<<m_tail<<endl;}int main(){    CMonkey monkey(10,20,30,40);    monkey.print();    return 0;}

多继承中子类
 

原创粉丝点击