C语言模拟实现C++中的继承和多态

这个问题主要考察的是C和C++的区别,以及C++中继承和多态的概念。
我们都知道C语言是面向过程的一种语言,C++则是面向对象的一类语言,而且C++是在C语言基础上进行改进的一类语言,所以C++有C所没有的的三大特性,它们分别是:封装,继承和多态,那仫什仫是继承和多态呢?
1、什仫是继承?
继承是一种复用手段,继承是类型之间的关系建模,共享共有的东西,实现各自本质不同的东西。
2、什仫是多态?
多态的字面意思就是”多种形态”,在C++中多态分为静态多态(重载)和动态多态。
静态多态/重载:函数名相同,函数参数不同(参数的个数和参数的类型),返回值可同可不同。
动态多态实现的条件:
1>、使用场景:父类的指针或者引用指向父类或者子类的对象(由赋值兼容规则决定);
2>、实现多态的两个条件:虚函数的重写父类的指针或者引用调用重写的虚函数。
3>、若父类中的成员函数加上virtual关键字,则子类中重写的该函数默认virtual,可以不指定,但是一般加上;
重写:子类重写父类的虚函数,要求函数名称,函数参数,返回值完全一样(协变除外);
C++中实现多态
我们知道的是在C++中会维护一张虚函数表,根据赋值兼容规则,我们知道父类的指针或者引用是可以指向子类对象的。如果一个父类的指针或者引用调用父类的虚函数则该父类的指针会在自己的虚函数表中查找自己的函数地址,如果该父类对象的指针或者引用指向的是子类的对象,而且该子类已经重写了父类的虚函数,则该指针会调用子类的已经重写的虚函数。下面是我画的一张图,方便记忆啦!
C语言模拟实现C++中的继承和多态_第1张图片
代码实现如下:

//C++中的多态
class B
{
public:
    B(const int& a=0)
        :_a(a)
    {}
    virtual void Print()
    {
        cout<<"B:"<<_a<protected:
    int _a;
};
class D:public B
{
public:
    D(const int& b=0)
        :_b(b)
    {}
    virtual void Print()
    {
        cout<<"D:"<<_b<protected:
    int _b;
};
void func(B *ptr)
{
    ptr->Print();
}
void TestCPP()
{
    B b(1);
    D d(2);
    B *ptr=&b;
    ptr->Print();  //1
    ptr=&d;
    ptr->Print();  //2
    func(&b);  //1
    func(&d);  //2
}

C语言中模拟实现多态:
我们知道在C语言中是没有class类这个概念的,但是有struct结构体,我们可以考虑使用struct来模拟;但是在C语言的结构体内部是没有成员函数的,如果实现这个父结构体和子结构体共有的函数呢?我们可以考虑使用函数指针来模拟。但是这样处理存在一个缺陷就是:父子各自的函数指针之间指向的不是类似C++中维护的虚函数表而是一块物理内存,如果模拟的函数过多的话就会不容易维护了。
下面是我画的一张理解C语言中继承的图:
C语言模拟实现C++中的继承和多态_第2张图片
下面是实现的代码:

//C语言模拟实现继承和多态

typedef void (*FUNC)();    //使用函数指针来模拟实现

struct B   //父类
{
    FUNC _func;
    int _a;
};
struct D  //子类
{
    B _ca;   
    int _b;
};
void B_Func()   //父类的成员函数
{
    printf("B:_func()\n");
}
void D_Func()   //子类的成员函数
{
    printf("D:_func()\n");
}
//父类的指针可以指向父类或者子类的对象
void func(B *ptr) //公有的接口
{
    ptr->_func();
}
void TestC()
{
    B b;
    D d;
    //对父类和子类的成员函数进行初始化
    b._func=B_Func;
    d._ca._func=D_Func;
     //父类的对象调用父类的成员函数
    b._func();
    //子类的对象要调用自己的成员函数,需要先找到自己继承过来的父类的函数指针再调用父类的成员函数
    d._ca._func();


    B *ptr=&b;   //一个父类的指针指向父类的对象
    ptr->_func();
    ptr=(B *)&d; //父类的指针也可以指向子类的对象,在C语言中需要强制类型转换
    ptr->_func();
    func(&b);
    func((B *)&d);
}

在这里就分享结束了~~~

你可能感兴趣的:(剑指offer刷题,C/C++)