c语言实现面向对象的基础思想

本文适合会C语言,并了解面向对面思想的同志。如果连多态还 不了解的话,就可以不用看了;

代码为随手打的,看思路为紧,下面说的类就是结构体

面向对象三要素:封装,继承,多态,

1:先说封装

:假设A类有成员变量int  ,成员函数void fun(), 没有实现的成员函数 void fun2(),相当于一个虚函数

实现就是struct而已,成员函数用函数指针实现.

 

typedef struct A{

    int x;

    void (*fun)();
    
    void (*fun2)();  //在这个代码段没有给这个函数指针赋值(看A_init函数),相当于这是一个虚函数。

}A;

void fun(A *this) 

{

printf("调用A类成员变量X = %d\n",this->x);

}

类A的init函数 ,可以理解为构造函数

void A_init( A* this )

{

    this->x = 0;

    this->fun = &fun();

}

 

封装还是很简单的。

2:继承

假设有上面的A类, B类继承至A类,则在B类中创建 A类成员(实际是struct 成员)就行了,同时实现类A未实现的函数fun2,可以理解为实现虚函数.

typedef struct B

{

    int  y;   
    struct A  a; //建议声明在开头,这里是为了体现offsetof 的妙用
}B; 

void fun2(A *this) 
{
    
    printf(“实现父类A的虚函数fun2 成员变量X=%d\n”,this->x);

}

void B_init(Struct B * this) //可以理解为B的构造函数
{
    A_init(& this->a );  //调用A的构造函数
    this->y = 0;
    this->a.fun2 = fun2;  //实现类A的虚函数
}

没错,上面就是继承,不然你以为有多复杂嘛

 

3:多态

多态的实现就是子类向上转型,和父类的向下转型(通过上面的虚函数,你应该有一点想法了吧),这里要介绍宏 offsetof. 当然也可以自己实现这个宏:  作用仅仅是算出结构体成员相对结构体开头的偏移量。

#define offsetof(TYPE,MEMBER)   (size_t)&((TYPE *)0)->MEMBER)

也可以用container_of替换,详细请移步:https://blog.csdn.net/GouplovXim1314/article/details/80445287

3.1  向上转型 

当你向上或向下转型时,说明你已经实现了基类A的虚函数fun2(),不同的子类有不同的实现,实质是函数指针指向的函数不同.



//在上面继承出,我们并没有对虚函数fun2()做该改变(向下转型),这使得我们无法使用类B的变量y,所以我们在这里重新构建类B,让大家看到多态的威力。

//以下代码与上面的代码无关
//**********************************类A 

typedef struct A{

    int x;

    void (*fun)();
    
    void (*fun2)();  //在这个代码段没有给这个函数指针赋值(看A_init函数),相当于这是一个虚函数。

}A;

void fun(A *this) 

{

printf("调用A类成员变量X = %d\n",this->x);

}

类A的init函数 ,可以理解为构造函数

void A_init( A* this )

{

    this->x = 0;

    this->fun = &fun();

}
//************************************类A结束
//************************************类B,继承至类A
typedef struct B

{
    int  y;   
    struct A  a; //建议声明在开头,这里是为了体现offsetof 的妙用
}B; 

void B_fun2(A *this)  //对虚虚函数有改变
{
    //向下转型到B,
    //请大家思考:为什么先把this转为char *,
    B *b_p = (B *)(char *)this - offsetof(B,a); 

    //在这么,我就可以调用B的函数和变量了
    printf(“实现父类A的虚函数fun2  A成员变量X=%d,B成员变量Y= %d\n”,this->x,b_p->y);

}

void B_init(Struct B * this) //可以理解为B的构造函数
{
    A_init(& this->a );  //调用A的构造函数
    this->y = 0;
    this->a.fun2 = B_fun2;  //实现类A的虚函数
}
//**************************************类B结束
//************************************类C,继承至类A
typedef struct C

{
    int  Z;   
    struct A  a; //建议声明在开头,这里是为了体现offsetof 的妙用
}C; 

void C_fun2(A *this)  //对虚虚函数有改变
{
    //向下转型到C,
    //请大家思考:为什么先把this转为char *,
    C *C_p = (C *)(char *)this - offsetof(C,a); 

    //在这么,我就可以调用C的函数和变量了
    printf(“实现父类A的虚函数fun2  A成员变量X=%d,C成员变量Z= %d\n”,this->x,C_p->Z);

}

void C_init(Struct C * this) //可以理解为B的构造函数
{
    A_init(& this->a );  //调用A的构造函数
    this->Z = 0;
    this->a.fun2 = C_fun2;  //实现类A的虚函数
}
//**************************************类B结束

//感受多态的威力吧

int main()
{
    struct B b;
    B_init( &b );  //在B的 init函数中会调用 A 的init函数
    struct C c;
    C_init(&c);

    //向上转型
    struct A *a_p = (Struct A *)offsetof(B,a);
    a_p->fun2();  //调用的是B_fun2;

    a_p = (Struct A *)offsetof(C,a);
    a_p->fun2();  //调用的是C_fun2;
   
    return 0;
}

 

以上为大概思路,建议大家看看LW_OOPC 库,简单又有技巧,对于深入理解 C 和 面向对象高级语言的底层原理  有帮助。

 

假设你已经会了多态,那么进一步就是用C语言实现基础的设计模式(比如工厂模式),不然你学面向对象干嘛呢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值