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

本文详细介绍了面向对象编程中的继承机制,包括公有、私有和保护继承的特点及应用场景,并通过实例展示了不同继承方式对成员函数的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

 

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

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

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;
}


多继承中子类
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值