精华内容
下载资源
问答
  • C语言实现类

    2017-11-02 20:10:24
    C语言实现类的封装、继承和多态,基类、派生类、结构体实现类
  • 继承就是当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。 举个例子:人是动物,人具有动物的行为和属性,但人...

    继承

    继承就是当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类
    举个例子:人是动物,人具有动物的行为和属性,但人也有动物所不具备的行为和属性。

    动物行为属性
     会动体力
    行为属性
     会动体力
     会学习智力

    继承的实现

    本实现使用了组合的方式,即把基类作为派生类的成员变量之一。
    但是一定要将基类放在派生类首部,这要基类和派生类的内存首部分布才一致。

    /* 基类 */
    typedef struct _animal_t animal_t;	/* 动物类 */
    struct _animal_t
    {
      unsigned int stamina;	/* 体力 */
    };
    
    /* 派生类 */
    typedef struct _human_t human_t;	/* 人类 */
    struct _human_t
    {
      animal_t ancestor;			/* 继承基类 */
      unsigned int intelligence;	/* 智力 */
    };
    

     

    内存布局示意图

     在派生类中的构造函数需要调用基类的构造函数用于初始化,然后再将构造函数创建的基类对象拷贝到派生类中。
    但由于是浅拷贝,即只拷贝了地址,没有拷贝地址的内容。所以要在派生类中加入基类指针成员变量,用于在析构函数释放内存。

    typedef struct _human_t human_t;/* 人类 */
    struct _human_t
    {
      animal_t ancestor;			/* 继承基类 */
      animal_t* p_ancestor;		/* 用于调用析构函数 */
      unsigned int intelligence;	/* 智力 */
    };
    human_t* human_born(void);		/* 构造函数 */
    void human_die(human_t* this);	/* 析构函数 */
    

     

    human_t* human_born(void)
    {
      human_t* this = malloc(sizeof(human_t));
    	
      /* 将构造好的基类复制 */
      this->p_ancestor = animal_born();
      memcpy(&(this->ancestor), this->p_ancestor, sizeof(animal_t));
    	
      this->intelligence = 60;
      printf("human_born: intelligence = %d\n", this->intelligence);
    
      return this;
    }
    
    void human_die(human_t* this)
    {
      printf("human_die\n");
      animal_die(this->p_ancestor);
      free(this);
    }
    

     由于在c语言下没有类型检查功能,在调用创建的类函数时就十分不安全,在基类加入基类类型名和类大小成员变量可以解决这个问题。
    基类类型名用于判断调用函数对象是否继承自该类,而类大小用于判断调用函数对象是基类还是派生类。(该方法只适用于线性继承,若有更合适的方法,请在评论区留下你宝贵的建议。)
    适用范围示意图

     

    typedef struct _animal_t animal_t;	/* 动物类 */
    struct _animal_t
    {
      char* type_name;			/* 基类类型名 */
      unsigned int class_size;	/* 类大小 */
    
      unsigned int stamina;	/* 体力 */
    };
    void act(void* this);		/* 动 */
    
    typedef struct _human_t human_t;/* 人类 */
    struct _human_t
    {
      animal_t ancestor;			/* 继承基类 */
      animal_t* p_ancestor;		/* 用于调用析构函数 */
      unsigned int intelligence;	/* 智力 */
    };
    void learn(void* this);
    
    void act(void* this)
    {
      animal_t* animal_this = (animal_t*)this;
      char* type_name = animal_this->type_name;
      /* 判断调用函数对象是否继承自该类 */
      if(0 == strcmp(type_name, "animal_t"))
      {
        printf("animal_act\n");
        animal_this->stamina -= 1;
        printf("stamina = %d\n", animal_this->stamina);
      }
      else
      {
        printf("can't act\n");
      }
    }
    
    void learn(void* this)
    {
      human_t* human_this = (human_t*)this;
      char* type_name = human_this->ancestor.type_name;
      unsigned int class_size = human_this->ancestor.class_size;
    
      /* 判断调用函数对象是否继承自该类 */
      /* 避免基类调用函数 */
      if((0 == strcmp(type_name, "animal_t")) &&
         (class_size >= sizeof(human_t)));
      {
        human_this->intelligence += 1;
        printf("human_learn: intelligence+1\n");
        printf("intelligence = %d\n", human_this->intelligence);
      }
      else
      {
        printf("can't learn\n");
      }
    }
    

    多态

    在上个例子中,人和动物都有会动的属性,但人的动作和动物的动作从表现上会有所不同。而多态就可以实现在同一个函数中,根据对象类型的不同,函数实现方式也不同。

    多态的实现

    c语言多态的实现,需要用到函数指针。函数名实际上是该函数代码存储空间的首地址,这个地址可以通过函数指针来存放。通过改变函数指针存储的地址就可以实现多态。

    typedef struct _animal_t animal_t;
    typedef void (*animal_act_t)(animal_t*);	/* 函数指针类型 */
    typedef struct _animal_vtable_t		/* 虚函数表 */
    {
      animal_act_t act;
    }animal_vtable_t;
    
    struct _animal_t
    {
      animal_vtable_t* vt;	/* 虚函数表指针存放到类中 */
      unsigned int stamina;
    };
    animal_t* animal_born(void);		/* 构造函数 */
    void act(void* this);	/* 函数接口 */
    void animal_die(animal_t* this);	/* 析构函数 */
    
    static void animal_act(animal_t* this);
    
    /* 动物类的虚函数表 */
    static animal_vtable_t __g_animal_vtable =
    {
      /* 将实现函数的首地址(函数名)赋值给函数指针 */
      .act = animal_act,
    };
    
    animal_t* animal_born(void)
    {
      animal_t* this = malloc(sizeof(animal_t));
    
      this->vt = &__g_animal_vtable;
    
      this->stamina = 100;
      printf("animal_born: stamina = 100\n");
    
      return this;
    }
    
    void act(void* this)
    {
      /* 通过虚函数表的函数指针调用实现函数 */
      return ((animal_t*)this)->vt->act(this);
    }
    
    /* 实现函数 */
    static void animal_act(animal_t* this)
    {
      if(this->stamina >= 30)
      {
        this->stamina -= 5;
        printf("animal act: stamina-5\n");
        printf("stamina = %d\n", this->stamina);
      }
      else
      {
        this->stamina += 10;
        printf("animal rest: stamina+10\n");
        printf("stamina = %d\n", this->stamina);
      }
    }
    
    void animal_die(animal_t* this)
    {
      free(this);
      printf("animal_die\n");
    }
    

    示例代码

    该代码将结合上述继承和多态的方法实现对基类函数进行重写:

    /* animal.h */
    #ifndef _ANIMAL_H_
    #define _ANIMAL_H_
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct _animal_t animal_t;
    
    typedef void (*animal_act_t)(animal_t*);
    
    typedef struct _animal_vtable_t
    {
      animal_act_t act;
    }animal_vtable_t;
    
    struct _animal_t
    {
      char* type_name;
      unsigned int class_size;
      animal_vtable_t* vt;
      unsigned int stamina;
    };
    
    animal_t* animal_born(void);
    void act(void* this);
    void animal_die(animal_t* this);
    
    #endif	/* _ANIMAL_H_ */
    
    /* animal.c */
    #include "animal.h"
    
    static void animal_act(animal_t* this);
    
    static animal_vtable_t __g_animal_vtable =
    {
      .act = animal_act,
    };
    
    animal_t* animal_born(void)
    {
      animal_t* this = malloc(sizeof(animal_t));
    	
      this->type_name = malloc(sizeof("animal_t"));
      memcpy(this->type_name, "animal_t", sizeof(this->type_name));
      this->class_size = sizeof(animal_t);
    	
      this->vt = &__g_animal_vtable;
    
      this->stamina = 100;
    
      printf("animal_born: stamina = 100\n");
    
      return this;
    }
    
    void act(void* this)
    {
      if(0 == strcmp(((animal_t*)this)->type_name, "animal_t"))
      {
        return ((animal_t*)this)->vt->act(this);
      }
      printf("can't act\n");
    }
    
    static void animal_act(animal_t* this)
    {
      if(this->stamina >= 30)
      {
        this->stamina -= 5;
        printf("animal act: stamina-5\n");
        printf("stamina = %d\n", this->stamina);
      }
      else
      {
        this->stamina += 10;
        printf("animal rest: stamina+10\n");
        printf("stamina = %d\n", this->stamina);
      }
    }
    
    void animal_die(animal_t* this)
    {
      free(this->type_name);
      free(this);
      printf("animal_die\n");
    }
    
    /* human.h */
    #ifndef _HUMAN_H_
    #define _HUMAN_H_
    
    #include "animal.h"
    
    typedef struct _human_t human_t;
    
    typedef void (*human_learn_t)(human_t*);
    
    typedef struct _human_vtable_t
    {
      human_learn_t learn;
    }human_vtable_t;
    
    struct _human_t
    {
      animal_t ancestor;
      animal_t* p_ancestor;
      human_vtable_t* vt;
      unsigned int intelligence;
    };
    
    human_t* human_born(void);
    void learn(void* this);
    void human_die(human_t* this);
    
    #endif	/* _HUMAN_H_ */
    
    /* human.c */
    #include "human.h"
    
    static void human_act(human_t* this);
    static void human_learn(human_t* this);
    
    static animal_vtable_t __g_animal_vtable;
    static human_vtable_t __g_human_vtable =
    {
      .learn = human_learn,
    };
    
    human_t* human_born(void)
    {
      human_t* this = malloc(sizeof(human_t));
    	
      this->p_ancestor = animal_born();
      memcpy(&(this->ancestor), this->p_ancestor, sizeof(animal_t));
    	
      this->ancestor.class_size = sizeof(human_t);
      
      memcpy(&__g_animal_vtable, this->ancestor.vt, sizeof(animal_vtable_t));
      this->ancestor.vt = &__g_animal_vtable;
      this->ancestor.vt->act = human_act;
    	
      this->vt = &__g_human_vtable;
    	
      this->intelligence = 60;
    
      printf("human_born: intelligence = %d\n", this->intelligence);
    
      return this;
    }
    
    void learn(void* this)
    {
      char* type_name = ((human_t*)this)->ancestor.type_name;
      unsigned int class_size = ((human_t*)this)->ancestor.class_size;
      if((0 == strcmp(type_name, "animal_t")) &&
         (class_size >= sizeof(human_t)));
      {
        return ((human_t*)this)->vt->learn(this);
      }
    
      printf("can't learn\n");
    }
    
    static void human_act(human_t* this)
    {
      if(this->ancestor.stamina >= 30)
      {
        this->ancestor.stamina -= 1;
        printf("human act: stamina-1\n");
        printf("stamina = %d\n", this->ancestor.stamina);
      }
      else
      {
        this->ancestor.stamina += 5;
        printf("human act: stamina+5\n");
        printf("stamina = %d\n", this->ancestor.stamina);
      }
    }
    
    static void human_learn(human_t* this)
    {
      this->intelligence += 1;
      printf("human_learn: intelligence+1\n");
      printf("intelligence = %d\n", this->intelligence);
    }
    
    void human_die(human_t* this)
    {
      printf("human_die\n");
    	
      animal_die(this->p_ancestor);
      free(this);
    }
    
    /* main.c */
    #include "animal.h"
    #include "human.h"
    
    int main()
    {
      printf("\nanimal monkey:\n");
      animal_t* monkey = animal_born();
      act(monkey);
    	
      printf("\nanimal monkey learn:\n");
      learn(monkey);
    	
      animal_die(monkey);
    	
      printf("\nhuman qaq:\n");
      human_t* qaq = human_born();
      act(qaq);
      learn(qaq);
      human_die(qaq);
    
      system("pause");
    
      return 0;
    }
    

    结果如下:

    程序运行结果

    展开全文
  • C语言实现类继承

    千次阅读 2018-08-03 16:04:39
    [C语言]实现类效果 C语言是利用结构体来实现类的效果的。当然,跟类还是有不同,在C++中类的成员属性默认是私有(private)的,而结构体是公开的(public)。 那么应该如何实现类继承效果呢?我们可以利用结构体嵌套...

    [C语言]实现类效果

    C语言是利用结构体来实现类的效果的。当然,跟类还是有不同,在C++中类的成员属性默认是私有(private)的,而结构体是公开的(public)。

    那么应该如何实现类的继承效果呢?我们可以利用结构体嵌套来实现,将”父类“当作”子类“的一部分,那可不就是继承了吗?

    #include<stdio.h>
    typedef struct A{
    	int a;
    }A;
    typedef struct B{
    	struct A B_A;
    }B;
    int main(){
    	B b;
    	b.B_A.a = 10;
    	printf("%d\n",b.B_A.a);
    }
    //输出结果为10

    现在写一个继承[C语言]实现类效果中ppi类的例子,此处对ppi类中形参“struct ppi this”修改成了“struct ppi *this”,以解决参数类型不匹配问题。

    connect.h

    #ifdef __cplusplus  //******  ADD
    extern "C" {        //******  ADD
    #endif              //******  ADD
    
    #define LINUX
    
    #ifdef LINUX
    typedef struct connect{
    	int protocol_read;
    	int protocol_write;
    	struct ppi *PPI;
    	void (*Read)(struct connect this,int area,int para1,int para2,int para3);
    	void (*Write)(struct connect this,int area,int para1,int para2,int para3,int *value);
    }connect;
    
    
    
    connect *NewConnect(connect *this);
    void Read(struct connect this,int area,int para1,int para2,int para3);
    void Write(struct connect this,int area,int para1,int para2,int para3,int *value);
    #endif
    
    #ifdef __cplusplus
    }
    #endif

    connect.c

    #include<stdlib.h>
    #include<stdio.h>
    #include<stdbool.h>
    #include"nodavesimple.h"
    #include"setport.h"
    #include"ppi.h"
    #include"protocol.h"
    
    
    
    
    connect *NewConnect(connect *this){
    	this->protocol_read = 0;
    	this->protocol_write = 0;
    }
    
    void Read(struct connect this,int area,int para1,int para2,int para3){
    	switch(this.protocol_read){
    	case 0:
    		printf("para 'protocol_read' ERROR!\n");
    		break;
    	case 1:
    		this.PPI = (struct ppi*)malloc(sizeof(struct ppi));
    		NewPPI(this.PPI);
    		ReadBytes(this.PPI,area,para1,para2,para3,NULL);
    		free(this.PPI);
    		break;
    	default:
    		printf("this protocol is not support!\n");
    		break;
    	}
    }
    
    void Write(struct connect this,int area,int para1,int para2,int para3,int *value){
    	switch(this.protocol_write){
    	case 0:
    		printf("para 'protocol_read' ERROR!\n");
    		break;
    	case 1:
    		this.PPI = (struct ppi*)malloc(sizeof(struct ppi));
    		NewPPI(this.PPI);
    		WriteBytes(this.PPI,area,para1,para2,para3,value);
    		free(this.PPI);
    		break;
    	default:
    		printf("this protocol is not support!\n");
    		break;
    	}	
    }
    
    
    
    /*
    int main(){
    	ppi PPI;
    	NewPPI(&PPI);	
    	int a = 0x2F;
    //	PPI.WriteBytes(PPI,daveOutputs,0,0,1,&a);
    	PPI.ReadBytes(PPI,daveOutputs,0,0,2,NULL);
    	return 0;
    }//use to test ppi class && need delete protocol.h
    
    */

     

    展开全文
  • 例:C++中的一个“Person”//Person.h class Person { private: char* pFirstName; char* pLastName;public: Person(const char* pFirstName, const char* pLastName); //constructor ~Person(); //de

    在用C语言实现继承和多态之前我们再来回忆一下什么是继承和多态

    继承:就是在已有类的基础上派生出新的类,新的类中保留已有类的数据和行为,并 扩展一些新的功能。已有的类叫做:基类或父类,新的类叫做:派生类或子类

    多态:在面向对象的语言中多态就是接口的不同实现方式。同一个操作作用于不同的对象可以有不同的解释,会产生不同的结果。允许基类的指针指向派生类的对象。

    typedef void(*FUN)();      //定义一个函数指针来实现对成员函数的继承
    
    struct Base 
    {
        FUN _fun;   //由于C语言中结构体不能包含函数,故只能用函数指针在外面实现
    
        int _a;
    };
    
    struct Derived  
    {
        Base _a_;     //在子类中定义一个基类的对象即可实现对父类的继承
        int _b;
    };
    
    void _fB()       //父类的同名函数
    {
        printf("i am father\n");
    }
    void _fD()       //子类的同名函数
    {
        printf("i am son\n");
    }
    
    
    void Test()
    {
        Base _a; 
        Derived _b; 
        _a._fun = _fB;        //父类的对象调用父类的同名函数
        _b._a_._fun = _fD;    //子类的对象调用子类的同名函数
    
        Base* p2 = &_a;   //定义一个父类指针指向父类的对象
        p2->_fun();     //调用父类的同名函数
        p2 = (Base*)&_b;  //让父类指针指向子类的对象,由于类型不匹配所以要进行强转
        p2->_fun();     //调用子类的同名函数
    }
    
    int main()
    {
        Test();
        return 0;
    }
    展开全文
  • C语言实现封装、继承和多态

    千次阅读 2016-03-19 10:57:15
    C语言实现封装、继承和多态–通过创建一个VTable(virtual table)和在基类和派生对象之间提供正确的访问 如何实现 C 语言的继承和多态–通过函数指针来实现的继承与多态,简单明了,animal基类,cat,dog两个...

    参照

    C语言实现封装、继承和多态–通过创建一个VTable(virtual table)和在基类和派生类对象之间提供正确的访问

    如何实现 C 语言的继承和多态–通过函数指针来实现的继承与多态,简单明了,animal基类,cat,dog两个派生类

    技巧:用 C 语言实现程序的多态性–oid *:万能的指针“挂钩”

    【C】——C利用回调函数实现多态

    关于多态


    多态 (polymorphism) 一词最初来源于希腊语polumorphos,含义是具有多种形式或形态的情形。在程序设计领域,一个广泛认可的定义是“一种将不同的特殊行为和单个泛化记号相关联的能力”。

    然而在人们的直观感觉中,多态的含义大约等同于“同一个方法对于不同类型的输入参数均能做出正确的处理过程,并给出人们所期望获得的结果”,也许这正体现了人们对于多态性所能达到的效果所寄予的期望:使程序能够做到越来越智能化,越来越易于使用,越来越能够使设计者透过形形色色的表象看到代码所要触及到的问题本质。

    作为读者的你或许对于面向对象编程已有着精深的见解,或许对于多态的方便与神奇你也有了深入的认识。这时候你讶异的开始质疑了:“多态,那是面向对象编程才有的技术,C 语言是面向过程的啊!”而我想说的是,C 语言作为一种编程语言,也许并不是为了面向对象编程而设计,但这并不意味着它不能实现面向对象编程所能实现的功能,就比如说,多态性。

    C语言能够模拟实现面向对象语言具有的特性,包括:多态,继承,封装等,现在很多开源软件都了用C语言实现了这几个特性,包括大型开源数据库系统postgreSQL,可移植的C语言面向对象框架GObject,无线二进制运行环境BREW。采用C语言实现多态,继承,封装,能够让软件有更好的可读性,可扩展性。另外,在 Linux 内核里面也大量使用了面向对象的思想,比如虚拟文件系统,设备驱动等模。

    C的多态性


    C的封装


    在C语言中,可以用结构+函数指针来模拟类的实现,而用这种结构定义的变量就是对象。

    封装的主要含义是隐藏内部的行为和信息,使用者只用看到对外提供的接口和公开的信息。

    有两种方法实现封装:

    • 利用C语言语法。在头文件中声明,在C文件中真正定义它
      这样可以隐藏内部信息,因为外部不知道对象所占内存的大小,所以不能静态的创建该类的对象,只能调用类提供的创建函数才能创建。这种方法的缺陷是不支持继承,因为子类中得不到任何关于父类的信息。

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

    头文件中声明,在源文件中定义


    这样可以隐藏内部信息,因为外部不知道对象所占内存的大小,所以不能静态的创建该类的对象,只能调用类提供的创建函数才能创建。这种方法的缺陷是不支持继承,因为子类中得不到任何关于父类的信息。

    头文件:point.h

    //头文件: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

    //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_);
    
    }

    隐藏私有数据


    把私有数据信息放在一个不透明的priv变量或者结构体中。只有类的实现代码才知道priv或者结构体的真正定义。
    头文件:point.h

    #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

    //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;
    }
    
    

    C的继承


    内存管理new/delete

    内存管理类new.h

    //内存管理类new.h
    
    #ifndef NEW_H
    
    #define NEW_H
    
    void * new (const void * class, ...);
    
    void delete (void * item);
    
    void draw (const void * self);
    
    #endif
    
    

    内存管理类的C文件:new.c

    //内存管理类的C文件:new.c
    
    #include "new.h"
    
    #include "base.h"
    
    void * new (const void * _base, ...)
    {
    
        const struct Base * base = _base;
    
        void * p = calloc(1, base->size);
    
        assert(p);
    
        *(const struct Base **) p = base;
    
        if (base ->ctor)
        {
            va_list ap;
            va_start(ap, _base);
    
            p = base ->ctor(p, &ap);
    
            va_end(ap);
        }
    
        return p;
    }
    
    void delete (void * self)
    {
    
        const struct Base ** cp = self;
    
        if (self && * cp && (* cp) —> dtor)
        {
            self = (* cp) —>dtor(self);
        }
        free(self);
    }
    
    void draw (const void * self)
    {
        const struct Base * const * cp = self;
        assert(self &&* cp && (* cp)->draw);
    
        (* cp) ->draw(self);
    }
    

    基类Base


    基类:base.h

    //基类:base.h
    
    #ifndef BASE_H
    
    #define BASE_H
    
    struct Base
    {
        size_t size; //类所占空间
    
        void * (* ctor) (void * self, va_list * app); //构造函数
    
        void * (* dtor) (void * self); //析构函数
    
        void (* draw) (const void * self); //作图
    };
    
    #endif

    内存管理类的C文件:new.c

    //内存管理类的C文件:new.c
    
    #include "new.h"
    
    #include "base.h"
    
    void * new (const void * _base, ...)
    
    {
    
        const struct Base * base = _base;
    
        void * p = calloc(1, base->size);
    
        assert(p);
    
        * (const struct Base **) p = base;
    
        if (base ->ctor)
        {
            va_list ap;
    
            va_start(ap, _base);
    
            p = base ->ctor(p, &ap);
    
            va_end(ap);
    
        }
        return p;
    }
    
    void delete (void * self)
    {
        const struct Base ** cp = self;
    
        if (self && * cp && (* cp) —> dtor)
        {
            self = (* cp) —>dtor(self);
        }
        free(self);
    }
    
    void draw (const void * self)
    {
    
        const struct Base * const * cp = self;
    
        assert(self &&* cp && (* cp)->draw);
    
        (* cp) ->draw(self);
    }
    

    point类


    Point头文件(对外提供的接口):point.h

    //Point头文件(对外提供的接口):point.h
    
    #ifndef   POINT_H
    
    #define  POINT_H
    
    extern const void * Point;                /* 使用方法:new (Point, x, y); */
    
    #endif

    Point内部头文件(外面看不到):point.r

     #ifndef POINT_R
     #define POINT_R
    
    struct Point
    {
        const void * base; //继承,基类指针,放在第一个位置,const是防止修改
        int x, y;        //坐标
    };
    
    #endif

    Point的C文件:point.c

    //Point的C文件:point.c
    
    #include "point.h"
    
    #include "new.h"
    
    #include "point.h"
    
    #include "point.r"
    
    static void * Point_ctor (void * _self, va_list * app)
    {
    
        struct Point * self = _self;
    
        self->x = va_arg(*app, int);
    
        self->y = va_arg(*app, int);
    
        return self;
    
    }
    
    static void Point_draw (const void * _self)
    {
    
        const struct Point * self = _self;
    
        printf("draw (%d,%d)", self -> x, self -> y);
    }
    
    static const struct Base _Point = 
    {
        sizeof(struct Point), Point_ctor, 0, Point_draw
    };
    
    const void * Point = &_Point;

    派生类Circle


    Circle头文件(对外提供的接口):circle.h

    //Circle头文件(对外提供的接口):circle.h
    
    #ifndef   CIRCLE_H
    
    #define  CIRCLE_H
    
    extern const void *Circle;                /* 使用方法:new (Point, x, y); */
    
    #endif

    Circle内部头文件(外面看不到):circle.r

    //Circle内部头文件(外面看不到):circle.r
    
    #ifndef CIRCLE_R
    
    #define CIRCLE_R
    
    struct Circle
    {
        const struct Point point; //放在第一位,可表继承
        int radius;
    };
    
    #endif

    Cricle的C文件:Cricle.c

    //Cricle的C文件:Cricle.c
    
    #include "new.h"
    
    #include "point.h"
    #include "point.r"
    
    #include "circle.h"
    #include "circle.r"
    
    
    static void * Cricle_ctor (void * _self, va_list * app)
    {
    
        struct Cricle * self = _self;
    
        self->x = va_arg(*app, int);
    
        self->y = va_arg(*app, int);
    
        return self;
    
    }
    
    static void Cricle_draw (const void *_self)
    {
    
        const struct Cricle * self = _self;
    
        printf("draw (%d,%d), radius = %d", self->x, self->y, self->radius);
    }
    
    static const struct Base _Cricle = 
    {
        sizeof(struct Cricle), Cricle_ctor, 0, Cricle_draw
    };
    
    const void * Cricle = &_Cricle;

    C的多态


    //测试程序:main.c
    
    #include "point.h"
    
    #include "new.h"
    
    int main (int argc, char ** argv)
    {
        void * p = new(Point, 1, 2);
    
        draw(p);
    
        delete(p);
    }
    展开全文
  • C语言如何实现继承及容器

    千次阅读 2020-03-31 21:49:16
    继承的概念 继承是面向对象软件技术当中的一个概念,与多态、封装共为面向对象的三个基本特征。...但是对于 C 语言来讲,其中并不存在的概念,那又如何实现继承呢 ? C 语言继承实现 笔者了解到 C 语言实现继承...
  • 用struct来模拟实现,因为struct在C和C++中都能可以使用,在C中称为结构体在C++中称为,但他们的原理是一样的,又因为struct的限定符默认是公有的,在C中没有限定符这个概念,所以用C语言只能
  • c语言实现继承和多态

    2017-08-04 19:18:22
    概念:继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有特性的基础上进行扩展,增加功能。这样产生新的,称派生继承呈现了面向对象程序设计的层次结构,体现由简单到复杂的...
  • C语言实现继承和多态

    万次阅读 2016-08-13 16:17:46
    C语言实现继承和多态 继承和多态是面向对象语言最强大的功能。有了继承和多态,我们可以完成代码重用。在C中有许多技巧可以实现多态。本文的目的就是演示一种简单和容易的技术,在C中应用继承和多态。通过创建一个...
  • C语言实现继承与多态

    2017-04-18 19:21:54
    在前面博客已经详细讲过...即派生中拥有基类的成员变量和成员函数,所以C语言实现如下: #include typedef void(*Func)(void); void funB() { printf("B::funB()\n"); } typedef struct B { int _b; Func _fb
  • C语言类继承和派生

    千次阅读 2013-09-05 17:16:41
    在模块的封装(一):C语言类的封装中,我们介绍了如何使用C语言的结构体来实现一个的封装,并通过掩码结构体的方式实 现了成员的保护。这一部分,我们将在此基础上介绍C语言类继承和派生。其实继承和派生是...
  • C语言实现封装、继承、多态

    千次阅读 2020-07-03 15:00:03
    C语言实现封装、继承、多态 文章目录C语言实现封装、继承、多态一. 封装二.继承三. 多态 一. 封装 C语言中虽然没有,但有struct和指针。我们可以在一个struct中存入数据和函数指针,以此来模拟行为。 typedef ...
  • C语言实现简单封装继承机制

    万次阅读 2016-02-21 12:09:53
    0 继承是OO设计的基础继承是OO设计中的基本部分,也是实现多态的基础,C++,C#,Objective-C,...下面我们就来看看如何用C语言实现继承。1 内存布局层面上继承的含义如今几乎所有程序员都知道继承的抽象含义,对于被用
  • C语言实现封装、继承

    2020-02-19 10:15:22
    1.C语言实现封装 ** 在C语言当中,是不存在封装这一个特性的,我们要实现它,我们可以借助两个方法: 1.利用C语言中的头文件,在头文件中进行声明,在C文件中对它进行定义,这样就可以隐藏内部信息,用户只能看到...
  • 一、面向对象与面向过程说到C语言和C++的区别有人就会说C语言是面向过程的语言,而C++是面向对象的语言。那么到什么是面向过程?什么又是面向对象呢?下面我就简单的说说我对与面向过程和面向对象的认识。 1)什么...
  • C语言实现封装,继承

    千次阅读 2016-09-17 14:34:50
    1.C语言实现封装在C语言当中,是不存在封装这一个特性的,我们要实现它,我们可以借助两个方法:1.利用C语言中的头文件,在头文件中进行声明,在C文件中对它进行定义,这样就可以隐藏内部信息,用户只能看到接口和...
  • 利用C语言实现C++里面的继承和多态特性 先来看看C++里面的继承和多态: 代码: class A { public: virtual void fun() { printf("A::fun()\n"); } int _a; }; class B :public A//B继承A { pu....
  • //C语言struct不能包含函数,故需要在实现 int _a; }; struct _B //子类 { _A aa; //通过子类包含父类对象实现继承 int _b; }; //定义两个函数---通过函数指针来决定指向那个函数实现多态 void _funA() //...
  •  在模块的封装(一):C语言类的封装中,我们介绍了如何使用C语言的结构体来实现一个的封装,并通过掩码结构体的方式实 现了成员的保护。这一部分,我们将在此基础上介绍C语言类继承和派生。其实继承和派生是...
  • C语言实现C++的继承

    2019-04-29 14:41:39
    #include <iostream> using namespace std;...//C++中的继承与多态 struct A { virtual void fun() //C++中的多态:通过虚函数实现 { cout<<"A:fun()"<<endl; } int a; }; struct B:publ...
  • 继承和多态是C++的特性,它C语言...用struct来模拟实现,因为struct在C和C++中都能可以使用,在C中称为结构体在C++中称为,但他们的原理是一样的,又因为struct的限定符默认是公有的,在C中没有限定符这个概念,所以
  • C实现一个struct A和struct B各包含一个int成员a和b,要求达到B继承了A的效果,也就是B里面包含一个A。并且能达到多态的效果,也就是一个A*p指向A调的是A的函数,指向B调用的是B的函数何为继承 ? 定义:在C++中...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 72,416
精华内容 28,966
关键字:

c语言实现类继承

c语言 订阅