C语言实现C++的封装继承与多态

1、 概述
C语言是一种面向过程的程序设计语言,而C++是在C语言基础上衍生来了的面向对象的语言,实际上,很多C++实现的底层是用C语言实现的,如在Visual C++中的Interface其实就是struct,查找Interface的定义,你可以发现有这样的宏定义:

#ifndef Interface
#define Interface struct
#endif

C++在语言级别上添加了很多新机制(继承,多态等),而在C语言中,我们也可以使用这样的机制,前提是我们不得不自己实现。
本文介绍了用C语言实现封装,继承和多态的方法。
2、 基本知识
在正式介绍C语言实现封装,继承和多态事前,先介绍一下C语言中的几个概念和语法。
(1) 结构体
在C语言中,常把一个对象用结构体进行封装,这样便于对对象进行操作,比如:

strcut Point{

int x;

int y;

};

结构体可以嵌套。因而可以把一个结构体当成另一个结构体的成员,如:

struct Circle {

struct Point point_;

int radius;

};

该结构体与以下定义完全一样(包括内存布置都一样):

struct Circle {

int x;

int y;

int radius;

};

(2) 函数指针
函数指针是指针的一种,它指向函数的首地址(函数的函数名即为函数的首地址),可以通过函数指针来调用函数。
如函数:

int func(int a[], int n);

可以这样声明函数指针:

int (*pFunc)(int a[], int n);

这样使用:

pFunc = func;
(*pFunc)(a, n);【或者PFunc(a, n)】

可以用typedef定义一个函数指针类型,如:

typdef int (*FUNC)(int a[], int n)

可以这样使用:

int cal_a(FUNC fptr, int a[], int n)
{
//实现体
}

(3) extern与static
extern和static是C语言中的两个修饰符,extern可用于修饰函数或者变量,表示该变量或者函数在其他文件中进行了定义;static也可用于修饰函数或者变量,表示该函数或者变量只能在该文件中使用。可利用它们对数据或者函数进行隐藏或者限制访问权限。

3、 封装
在C语言中,可以用结构+函数指针来模拟类的实现,而用这种结构定义的变量就是对象
封装的主要含义是隐藏内部的行为和信息,使用者只用看到对外提供的接口和公开的信息。有两种方法实现封装:
(1) 利用C语言语法。在头文件中声明,在C文件中真正定义它
这样可以隐藏内部信息,因为外部不知道对象所占内存的大小,所以不能静态的创建该类的对象,只能调用类提供的创建函数才能创建。这种方法的缺陷是不支持继承,因为子类中得不到任何关于父类的信息。如:

//头文件:point.h

#ifndef POINT_H

#define POINT_H

struct Point;

typedef struct Point point;

point * new_point(); //newer a point object

void free_point(point *point_);// free the allocated space

#endif

//C文件:point.c

#include”point.h”

strcut Point

{

int x;

int y;

};

point * new_point()

{

point * new_point_ = (point *) malloc(sizeof(point));

return new_point_;

}

void free_point(point *point_)

{

if(point_ == NULL)

return;

free(point_);

}

我们在使用point.h中的函数时,我们只能看见接口函数,并不能看见其定义和实现。

(2) 把私有数据信息放在一个不透明的priv变量或者结构体中。只有类的实现代码才知道priv或者结构体的真正定义。如:

#ifndef POINT _H

#define POINT_H

typedef struct Point point;

typedef struct pointPrivate pointPrivate;

strcut Point

{

Struct pointPrivate *pp;

};

int get_x(point *point_);

int get_y(point *point_);

point * new_point(); //newer a point object

void free_point(point *point_);// free the allocated space

#endif

//C文件:point.c

#include”point.h”

struct pointPrivate

{

int x;

int y;

}

int get_x(point *point_)

{

return point_->pp->x;

}

int get_y(point *point_)

{

return point_->pp->y;

}

//others…..

二、继承与多态的概念
继承:是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性 和行为,并能扩展新的能力,已有类被称为父类/基类,新增加的类被称作子类/派生类。
多态:按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同现方式即为多态。同一操作作 用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。简单说就是允许基类的 指针指向子类的对象。
实现:


//C++中的继承与多态
struct A
{
    virtual void fun() //C++中的多态:通过虚函数实现
    {
        cout << "A:fun()" << endl;
    }

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

    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 Test1()
{
    //测试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();  //调用子类的同名函数
}

原文:http://dongxicheng.org/cpp/ooc/http://www.php8.org/C/113695.html

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值