C++ 单继承 父类和子类

1.如果派生类的继承方式为public,则这样的派生类称为基类的子类;
2. C++ 允许父类指针指向子类对象,父类引用子类对象,无须通过强制类型转换保持赋值类型相容,因为子类对象isa父类对象,编译时按父类说明的权限访问成员;
3. 通过父类指针调用虚函数进行晚期绑定,根据对象的实际类型绑定到核实的实例成员函数;
4. 父类指针可视为泛型函数,配合虚函数产生多态行为;
示例代码
#include <iostream>

using namespace std;
class POINT{
int x, y;
public:
int getx( ){ return x; } int gety( ){ return y; }
void show( ){ cout<<"Show a point\n"; }
POINT(int x,int y): x(x), y(y){ }
};
class CIRCLE: public POINT{//公有继承,基类和派生类构成父子关系
int r;
public:
int getr( ){ return r; } void show( ){ cout<<"Show a circle\n"; }
CIRCLE(int x, int y, int r):POINT(x,y){ CIRCLE::r=r; }
} c(3,7,8);
void main(void){
POINT *p=&c;//父类指针p指向子类对象,不用类型转换p=(POINT*)&c
cout<<c.getr( )<<p->getx( );//不能用p->getr( ),编译时无POINT::getr( )
p->show( ); //p指向子类对象,但调用的是POINT::show( )
}
输出结果
r: 8 ,x: 3
show a point
5.在派生类的函数成员内部,基类指针可以直接指向该派生类对象,即对派生类的函数成员而言,基类被等同地当做派生类的父类;
6.如果一个函数声明为基类的友元,则友元函数内部的基类指针也可以直接指向派生类对象,即对基类的友元函数而言,基类被等同的当做派生类的父类;
7.同理,在上述两种情况下,基类引用可直接引用派生类对象(泛型引用)。
示例代码
#include <iostream>

using namespace std;

class VECHILE{
    int speed,weight,wheels;
    public:
    VECHILE(int spd,int wgt,int whl);
    friend void main();
};
VECHILE::VECHILE(int spd,int wgt,int whl)
{
    speed = spd;
    weight = wgt;
    wheels = whl;
}
class CAR:VECHILE{
    int seats;
    public:
    VECHILE *who();
    CAR(int sd,int wt, int st):VECHILE(sd,wt,4)
    {
        seats = st;
    }
};
VECHILE *CAR::who()
{
    VECHILE *p = this;//派生类内的基类指针直接指向派生类对象:泛型
    VECHILE &q = *this;//派生类内基类有值引用直接引用派生类对象:泛型
    return p;

}
void main(void)
{
    CAR c(1,2,3);
    VECHILE *p = &c;//编译器报错,不可对不可访问的基类“VECHILE”进行转换
    //return 0;
}
8.派生类的存储空间
  • 派生类的成员一部分是新定义的,另一部分是从基类
    继承而来的,在派生类对象的存储空间中必然包含了
    基类的数据成员;
  • 在构造派生类对象之前,先构造或初始化基类对象的
    存储空间,作为派生类对象存储空间的一部分;
  • 在计算派生类对象存储空间时,基类和派生类的静态
    数据成员
    都不应计算在内。
示例代码
#include <iostream>

using namespace std;
class A{
    int h,i,j;
    static int k;//必须在类体外初始化
};
class B:A{
    int m,n,p;
    const static int q = 0;//const 只能在体外或者体内一处有值
};
int A::k = 0;//静态数据成员必须初始化
int main()
{
    cout << "size of int : " << sizeof(int) << endl;
    cout << "size of A :" << sizeof(A) << endl;
    cout << " size of B :" << sizeof(B) << endl;
    system("pause");
    return 0;
}

运行结果
size of int : 4
size of A :12
 size of B :24
示例代码
class BAG
{
    int *const e;
    const int s;
    int p;

public:
    BAG(int m) : e(new int[m]), s(e ? m : 0) { p = 0; }
    ~BAG()
    {
        if (e)
        {
            delete e;
            *(int *)&s = 0;
            *(int **)&e = 0; //0代表空指针
        }
    }
    int getp() { return p; }
    int have(int f)
    {
        for (int i = 0; i < p; i++)
        {
            if (e[i] == f)
                return 1;
            return 0;
        }
    }
};
class SET:protected BAG{//不允许重复的元素,故须覆盖基类的pute
    public:
    BAG::getp;
    BAG::have;//从保护恢复为public
    int pute( int f)
    {
        return have(f)?1:BAG::have(f); //不能去掉BAG::,递归
    }
    SET(int m):BAG(m){ } //C++缺省的析构函数~SET( )自动调用~BAG( )
};//若定义析构函数,形式为~SET( ){ },功能同缺省析构函数
发布了52 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/jzj_c_love/article/details/102730350