多态的C语言实现版本
#ifndef _51_2_H
#define _51_2_H
typedef void Demo;
typedef void Derived;
Demo* Demo_create(int i,int j);
int Demo_geti(Demo*pthis);
int Demo_getj(Demo*pthis);
int Demo_add(Demo*pthis,int value);
void Demo_free(Demo*pthis); Derived*Derived_create(int i,int j,int k);
int Derived_getk(Derived*pthis);
int Derived_add(Derived*pthis,int value);
#endif
#include<stdio.h>
#include"51-2.h"
#include<malloc.h>
//定义父子类的虚函数
static int Demo_virtual_add(Demo*pthis,int value);
static int Derived_virtual_add(Derived*pthis,int value);
//2。确定虚函数表的类型,虚函数表的结构体,用来创建虚函数表,存储虚函数地址
//目的是为了实现add函数的多态
struct vtbl{
int(*padd)(Derived*,int);//3。函数指针的定义
};
struct classdemo{
struct vtbl* vptr;//1。定义虚函数表指针,指针的类型
int mi;
int mj;
};
static struct vtbl g_Demo_vtbl = {
Demo_virtual_add
};//4。全局虚函数表变量,static关键字将该变量隐藏在此文件中,外部不能访问
static struct vtbl g_Derived_vtbl = {
Derived_virtual_add
};
struct classderived{
struct classdemo d;
int mk;
};
Demo* Demo_create(int i,int j){
struct classdemo* ret = (struct classdemo*)malloc(sizeof(struct classdem o));//分配空间
if(ret != NULL){
ret->vptr = &g_Demo_vtbl;//5。将虚函数表和具体对象关联起来
ret->mi = i;
ret->mj = j;
}
return ret;
}
int Demo_geti(Demo*pthis){//具体实现函数 强制类型转换
struct classdemo* obj = (struct classdemo*)pthis;
return obj->mi;
}
int Demo_getj(Demo*pthis){
struct classdemo* obj = (struct classdemo*)pthis;
return obj->mj;
}
//6。分析、实现具体的虚函数
static int Demo_virtual_add(Demo*pthis,int value){
struct classdemo* obj = (struct classdemo*)pthis;
return obj->vptr->padd(pthis,value);
}
int Demo_add(Demo*pthis,int value){
struct classdemo* obj = (struct classdemo*)pthis;
return obj->mi + obj->mj + value;
}
void Demo_free(Demo*pthis){
free(pthis);
}
Derived*Derived_create(int i,int j,int k){
struct classderived* ret = (struct classderived*)malloc(sizeof(struct cl assderived));
if(ret != NULL){
ret->d.vptr = &g_Derived_vtbl;//关联到子类的虚函数表上去
ret->d.mi = i;
ret->d.mj = j;
ret->d.mi = i;
ret->d.mj = j;
ret->mk = k;
}
return ret;
}
int derived_getk(Derived* pthis){
struct classderived* obj = (struct classderived*)pthis;
return obj->mk;
}
static int Derived_virtual_add(Derived*pthis,int value){
struct classderived* obj = (struct classderived*)pthis;
return obj->mk + value;
}
int Derived_add(Derived*pthis,int value){
struct classderived* obj = (struct classderived*)pthis;
return obj->d.vptr-> padd(pthis,value);
}
#include<stdio.h>
#include"51-2.h"
void run(Demo*p,int v){
int r = Demo_add(p,v);
printf("r=%d\n",r);
}
int main(){
Demo* pb = Demo_create(,);
Demo* pd = Derived_create(,,); printf("Demo_add(3)=%d\n",Demo_add(pb,));
printf("Derived_add(3)=%d\n",Derived_add(pd,)); run(pb,);
run(pd,);
Demo_free(pb);
Demo_free(pd);
return ;
}
多态的C语言实现版本的更多相关文章
- go语言最新版本 下载地址
国内官方网站无法打开.放在了百度云中,定期会更新: 链接:http://pan.baidu.com/s/1dD59duh 密码:46ek 备用地址:http://pan.baidu.com/s/1hq ...
- 如何在Visual studio中修改所使用C#语言的版本
有时候,我们需要在Visual studio里修改当前使用的C#语言的版本,具体修改方法如下:在solution explorer中右键工程->选择属性->切换到Build页->点击 ...
- 为什么说JAVA中要慎重使用继承 C# 语言历史版本特性(C# 1.0到C# 8.0汇总) SQL Server事务 事务日志 SQL Server 锁详解 软件架构之 23种设计模式 Oracle与Sqlserver:Order by NULL值介绍 asp.net MVC漏油配置总结
为什么说JAVA中要慎重使用继承 这篇文章的主题并非鼓励不使用继承,而是仅从使用继承带来的问题出发,讨论继承机制不太好的地方,从而在使用时慎重选择,避开可能遇到的坑. JAVA中使用到继承就会有两 ...
- C# 语言历史版本特性(C# 1.0到C# 7.1汇总更新) C#各版本新特性 C#版本和.NET版本以及VS版本的对应关系
C# 语言历史版本特性(C# 1.0到C# 7.1汇总更新) 2017年08月06日 11:53:13 阅读数:6705 历史版本 C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有1 ...
- 微软的R语言发行版本MRO及开发工具RTVS
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:微软在收购R语言的开发商后,也独立发行或在自己的产品中集成了R语言,这里就介绍下它们包 ...
- C# 语言历史版本特性(C# 1.0到C# 8.0汇总)
历史版本 C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有17年的历史,语言本身具有丰富的特性,微软对其更新支持也十分支持.微软将C#提交给标准组织ECMA,C# 5.0目前是ECM ...
- MFC多语言程序版本,在不同的windows系统上的使用
如何使MFC程序界面支持多国语言?这次使用后给自己做一个总结. 我们使用vc6.0的版本来试验 1. 切换到资源视图,右键Dialog->Insert Copy 2. ok后,会出来一个语言的选 ...
- Python笔记(三)继承和多态、动态语言
一.继承 先定义一个A类 class A(object): def fun(self): print "Run A fun()" 在定义一个B类 class B(A): pass ...
- C# 语言历史版本特性(C# 1.0到C# 7.1汇总更新)
历史版本C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有17年的历史,语言本身具有丰富的特性,微软对其更新支持也十分支持.微软将C#提交给标准组织ECMA,C# 5.0目前是ECMA ...
随机推荐
- 解决iframe重定向让父级页面跳转
原文:http://www.jb51.net/article/40583.htm 有内嵌iframe的页面,当session过期时,点击连接重定向后的跳转会在iframe中跳转,在登录页面中加入下面的 ...
- ImportError: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found
问题背景描述: 在做图片验证码识别安装 tensorflow 启动程序报错: ImportError: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' no ...
- springboot中yml常用配置
server: port: 8080 spring: datasource: #数据源配置 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc: ...
- ios时间显示NaN
问题是当时js里时间是这种格式的 2016-09-07 16:37:50 用var time = obj.replace(/\-/g, "/");将格式改成 2016/09/07 ...
- iOS开发MD5、SHA1
MD5: + (NSString *)md5:(NSString *)input { const char *cStr = [input UTF8String]; unsigned char dige ...
- 剑指offer——数据结构
技术面重点:数组.字符串.链表.树.栈以及队列.
- BST and Heap详解
BST(Binary Search Tree) 基本特点: 二叉树 集合中的数据具有可比较大小的关键码 数据之间满足BST特性 中序遍历可得到一个递增的数据序列(可作为判断一棵二叉树是否是BST的方法 ...
- php实现ajax请求的方法
php实现ajax请求的方法 Ajax页面:第一,了解底层逻辑,正是平常的1个提交在无刷新的条件下发出请求后完成回应,之后去针对你需要的条件来做动作. <!DOCTYPE html> &l ...
- 资源在windows编程中的应用----菜单
资源在Windows编程中的应用 资源 加速键.位图.光标.对话框.菜单.字符串.工具条 1.菜单的创建 菜单由以下组成部分: (1)窗口主菜单条 (2)下拉式菜单框 (3)菜单项热键标识 (4)菜单 ...
- python数据类型 列表+元组
一:列表 二:元组 一:列表list: 1.列表中的每个元素都可变的,意味着可以对每个元素进行修改和删除: 2.列表是有序的,每个元素的位置是确定的,可以用索引去访问每个元素: 3.列表的所有元素放在 ...