C语言实现C++的三大特性(封装、继承和多态)

面向对象的程序设计有三大特性:封装、继承和多态。

封装

  • C++语言中支持数据封装,类是支持数据封装的工具,对象是数据封装的实现。在封装中,还提供一种对数据访问的控制机制,使得一些数据被隐藏在封装体内,因此具有隐藏性。封装体与外界进行信息交换是通过操作接口进行的

  • 封装性实际上是由编译器去识别关键字public、private和protected来实现的,体现在类的成员可以有公有成员(public),私有成员(private),保护成员(protected)。
    私有成员是在封装体内被隐藏的部分,只有类体内说明的函数(类的成员函数)才可以访问私有成员,而在类体外的函数时不能访问的,公有成员是封装体与外界的一个接口,类体外的函数可以访问公有成员,保护成员是只有该类的成员函数和该类的派生类才可以访问的。

  • 类是一种复杂的数据类型它是将不同类型的数据和与这些数据相关的操作封装在一起的集合体。因此,类具有对数据的抽象性,隐藏性和封装性

  • 封装性的目的是为了增加代码健壮性,减少写代码时出错的概率。也就是说只要能编译通过,在C++的类中无论是public、protected还是private,最终生成的汇编代码其实是一致的。

而继承和多态是C++对C语言的补充,使得代码写起来更加简单。

继承

  • C++语言允许单继承和多继承。继承是面向对象语言的重要特性,是实现抽象和共享的一种机制。

  • C++语言中的继承机制可以克服传统的面向过程程序设计的缺点,因为传统编程方式不能重复使用程序而造成资源的浪费,而c++语言提供了无限重复利用程序资源的一种新途径。

  • 一个类可以根据需要生成它的派生类,派生类还可以再生成派生类。派生类继承基类的成员,另外,还可以定义自己的成员。
    C++中的继承有两个方面的意思,第一子类拥有父类所有的成员变量,第二子类也拥有父类的所有成员函数,所以很多C++教材会说一句话,子类拥有父类的所有特性。

多态

  • 多态性是指对不同类的对象发出相同的消息将会有不同的实现。多态性也可以理解为,在一般类中定义的属性或服务被特殊类继承后,可以具有不同的数据类型或不同的实现。可见,多态性与继承性相关联。简单的说,多态性是指发出同样的消息被不同的数据类型的对象接收后导致不同的行为

  • C++语言支持多态性表现在

    1. C++语言允许函数重载和运算符重载。

    2. C++语言通过定义虚函数来支持动态联编,动态联编是多态性的一个重要的特征。

  • 多态特性的工作依赖虚函数的定义,在需要解决多态问题的重载成员函数前,加上virtual关键字,那么该成员函数就变成了虚函数,从上例代码运行的结果看,系统成功的分辨出了对象的真实类型,成功的调用了各自的重载成员函数。如果在基类某些函数前面声明为virtual,则C++编译器会在内存对象模型前面插入一个虚函数指针,该指针指向一个虚函数表,正是因为我们可以改变虚函数指针所指函数表地址,从而实现其多态操作。

  • 多态特性让程序员省去了细节的考虑,提高了开发效率,使代码大大的简化,当然虚函数的定义也是有缺陷的,因为多态特性增加了一些数据存储和执行指令的开销,所以能不用多态最好不用。

C语言实现封装性

属性方法(一般定义为函数指针)封装到特定结构体中。

怎样定义函数指针?

// 定义函数
int add(int x, int y)
{
    return x+y;
}

// 定义函数指针
int(*padd)(int , int ); //函数指针,指针变量的名字是padd
padd = add;

// 用typedef重命名
typedef int(*PADD)(int , int ); //注意typedef后要加分好,#define宏定义后没有分号
PADD padd;
padd = add;

C语言实现继承性

C++中类的成员变量的继承其实就相当于是C语言的结构体嵌套,而在写代码的时候可以省略其中父类的嵌套。
也可以在一个结构体里面定义另一个结构体的指针。

C语言实现多态性

#pragma once
#include 
using namespace std;

//C++中的继承与多态
struct A
{
    virtual void fun()    //C++中的多态:通过虚函数实现
    {
        cout<<"A:fun()"<int a;
};
struct B:public A         //C++中的继承:B类公有继承A类
{
    virtual void fun()    //C++中的多态:通过虚函数实现(子类的关键字virtual可加可不加)
    {
        cout<<"B:fun()"<int b;
};

//C语言模拟C++的继承与多态

typedef void (*FUN)();      //定义一个函数指针来实现对成员函数的继承

struct _A       //父类
{
    FUN _fun;   //由于C语言中结构体不能包含函数,故只能用函数指针在外面实现

    int _a;
};

struct _B         //子类
{
    _A _a_;     //在子类中定义一个基类的对象即可实现对父类的继承
    int _b;
};

void _fA()       //父类的同名函数
{
    printf("_A:_fun()\n");
}
void _fB()       //子类的同名函数
{
    printf("_B:_fun()\n");
}


void Test()
{
    //测试C++中的继承与多态
    A a;    //定义一个父类对象a
    B b;    //定义一个子类对象b

    A* p1 = &a;   //定义一个父类指针指向父类的对象
    p1->fun();    //调用父类的同名函数
    p1 = &b;      //让父类指针指向子类的对象
    p1->fun();    //调用子类的同名函数


    //C语言模拟继承与多态的测试
    _A _a;    //定义一个父类对象_a
    _B _b;    //定义一个子类对象_b
    _a._fun = _fA;        //父类的对象调用父类的同名函数
    _b._a_._fun = _fB;    //子类的对象调用子类的同名函数

    _A* p2 = &_a;   //定义一个父类指针指向父类的对象
    p2->_fun();     //调用父类的同名函数
    p2 = (_A*)&_b;  //让父类指针指向子类的对象,由于类型不匹配所以要进行强转
    p2->_fun();     //调用子类的同名函数
}

运行结果
C语言实现C++的三大特性(封装、继承和多态)_第1张图片

你可能感兴趣的:(C/C++)