c语言结构体模拟c++对象的方法,并实现this指针
来源:互联网 发布:阿里云备案拍照地点 编辑:程序博客网 时间:2024/05/16 17:32
先说一下结构体模拟对象的基本思路。
1. 在结构体里定义好函数指针。
2. 在结构体外面定义好对象的方法。
3. 在结构体初始化的时候把这些方法的地址赋值给对应的函数指针。
4. 通过函数指针调用函数,并把结构体自身的地址传给函数。
这个思路容易想到,但不是很完美。毕竟定义函数的时候必须多写一个参数指向结构体(即this指针必须通过参数显式传递),不方便。调用的时候也要多写一次对象的名字:obj.method(&obj,arg1,arg2,…)。
于是就有了一个改进的思路:this指针不通过参数传递,而是调用方法的时候临时放到一个全局变量里,到方法里面再取出来。并且可以借助宏来尽可能封装,简化这一过程。
先来看一下这个头文件:
/*jscobj.h*/#ifndef JSCOBJ_H#define JSCOBJ_H#define this m(self)#define m(pInst) ((pInst)->_method_(pInst))#define Define_Method(T) T * T##$Method(T *ps){_obj_arg_ = ps;return ps;}#define Define_Member(T) struct T * (* _method_)(struct T * ps);#define Declare_Method(T) T * T##$Method(T * ps);#define Register_Method(pInst,T) pInst->_method_ = T##$Method;#define MethodOf(T) T * self = (T *)_obj_arg_;extern void *_obj_arg_;#endif
/*jscobj.c*/#include "jscobj.h"void *_obj_arg_;
这里定义了七个宏一个全局变量。下面先来看具体的用法。
这里定义了一个Student类做例子
/*student.h*/#ifndef _STUDENT_H_#define _STUDENT_H_#include<stdio.h>#include<stdlib.h>#include"jscobj.h"typedef struct Student{ /****/Define_Member(Student)/****/ void (*printInfo)(); int (*getAge)(); int age; char name[10];}Student,*pStudent;/****/Declare_Method(Student)/****/int Student$getAge();void Student$printInfo();pStudent Student$$new(char *name,int age);void Student$$Ini(pStudent stu, char *name, int age);#endif
/*student.c*/#include "student.h"#include "string.h"/****/Define_Method(Student)/****/pStudent Student$$new(char *name, int age){ pStudent stu = (pStudent)malloc(sizeof(Student)); Student$$Ini(stu,name,age); return stu;}void Student$$Ini(pStudent stu,char *name, int age){ /****/Register_Method(stu,Student)/****/ stu->getAge = Student$getAge; stu->printInfo = Student$printInfo; stu->age = age; strcpy(stu->name,name);}int Student$getAge(){ /****/MethodOf(Student);/****/ return self->age;}void Student$printInfo(){ /****/MethodOf(Student);/****/ printf("name: %s, age: %d\n",this->name,this->getAge());}
如上,用到宏的地方着重标了一下。这些宏看起来就和注释差不多,但是实际上做了什么呢?
首先,Define_Member实际上在结构体里面定义了一个函数指针 _member_ ,然后Declare_Method 和 Define_Method 定义了一个函数,这个函数的作用就是把对象地址放到全局变量里面去。最后通过Register_Method把这个函数注册到_member_ 指针上,这样等于结构体多了一个隐藏的方法。
然后,来看下实际是怎么样调用方法的:
/*main.c*/#include<stdio.h>#include<stdlib.h>#include"student.h"int main(){ Student *stu = Student$$new("Jack",20); m(stu)->printInfo(); system("pause"); return 0;}
/*输出:*/name: Jack, age: 20
m(stu)->printInfo() 这里,展开m这个宏以后变成 ((stu)-> _method_(stu))->printInfo(); 也就是先用_method_把stu的地址放到全局变量以后再调用方法。接着在方法里面,第一行MethodOf(Student)把这个地址取出,并转化成一个Student指针,名字是self。这样,被调用的方法就知道是哪个对象调用它了。
最后,在方法里面,因为知道对象自己的地址就储存在self里面,那么通过self调用其他方法的时候就没必要再m(self),而可以通过另一个词this来替换掉m(self)。这样在方法内部,可以直接做到像this->getAge()这样的调用。这样this指针就通过宏实现了。
- c语言结构体模拟c++对象的方法,并实现this指针
- 简单的C语言结构体实现面向对象的方法
- C语言用结构体和指针实现面向对象编程
- C语言里用结构体和指针函数实现面向对象思想
- c语言结构体指针
- C语言---结构体指针
- 【C语言】结构体指针
- C语言实现类中方法 用函数指针在结构体中加入函数
- C语言指针学习笔记:指向结构体的指针
- C语言结构体指针,函数指针的用法
- C语言指针-----指针与结构体
- C语言结构指针
- C ++的this指针
- C语言基础:C语言结构体(5) - 指向结构体的指针
- 使用 JNA 模拟C语言结构体的完整源代码
- JNA—模拟C语言结构体
- C语言实现回文判断(利用指针的方法)
- c/c++返回结构体方法和this指针,平时总结
- Matlab中画参数方程图像
- 数据结构中的双向链表
- 登陆界面 记住密码功能
- 什么是架构师和如何成为一个架构师
- Unity5.5 Lighting Scene
- c语言结构体模拟c++对象的方法,并实现this指针
- AngularJS配置.run()块中设置路由事件的监听器以及过滤未经授权的请求。
- 关闭linux退格键和vi发出的嘟嘟声
- Android中自定义checkbox样式
- apache tomcat负载均衡
- WebService的两种方式SOAP和REST比较 (转)
- 国密SM1\ SM2\ SM3\ SM4\ SSF33算法和国际RSA算法的对应关系
- Android开发细节——开发过程中遇到的细节问题与解决方案汇总【转】
- ipynb后缀文件怎么打开