多态的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 ...
随机推荐
- windows下node配置npm全局路径(踩坑)
事情的起因是:Koa要求v7.6.0以上的nodejs. 但是window环境下升级node不容易,试过npm install -g n 和n stable等命令无效,而网上推荐的nvm并不支持win ...
- 腾讯几款QQ软件
1.QQ(普通版QQ) https://im.qq.com/ 2.Tim(QQ办公简洁版) https://tim.qq.com/ https://baike.baidu.com/item/Tim/2 ...
- flask之Blueprint蓝图
flask_Blueprint.py ''' flask中的Blueprint蓝图: (1)新建模块,例如Bp1.py,Bp2.py,在模块中创建蓝图实例 (2)通过app.register_blue ...
- poj2594最小路径覆盖+floyd
Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 8909 Accepted: 3 ...
- Java并发编程volatile关键字
volatile理解 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和volatile 关键字机制.volatile具有synchronized关键字的“可见性”,vo ...
- 掌握了Docker Layer Caching才敢自称精通Dockerfile
长话短说: 本次原创将向您展示在Docker中使用Layer Cache以加快镜像构建. 这个话题的初衷在于:应用程序打包过程是很慢的(下载并安装框架&第三方依赖包.生成assets),这在D ...
- python大量造数据
# -*- coding: utf-8 -*-# date=2020/1/21import timeimport pymysqlimport pymysql.cursors # 获取一个数据库连接,注 ...
- 面试中很值得聊的二叉树遍历方法——Morris遍历
Morri遍历 通过利用空闲指针的方式,来节省空间.时间复杂度O(N),额外空间复杂度O(1).普通的非递归和递归方法的额外空间和树的高度有关,递归的过程涉及到系统压栈,非递归需要自己申请栈空间,都具 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射
上一篇文章(https://www.cnblogs.com/meowv/p/12961014.html)集成了定时任务处理框架Hangfire,完成了一个简单的定时任务处理解决方案. 本篇紧接着来玩一 ...
- Rocket - util - Counters
https://mp.weixin.qq.com/s/q7R2Dn9p9cch_ABN4raReQ 介绍几种计数器的实现,以及其中的一点小细节. 1. ZCounter ...