文档章节

C语言的面向对象

谁染霜林醉
 谁染霜林醉
发布于 2014/09/12 13:42
字数 812
阅读 81
收藏 3

面向对象的思想,不应受某种语言的限制,面向过程的C语言同样如此。C里面没有类,可以用结构体;没有类的方法,可以使用函数指针;

最重要的,没有继承的概念,怎么解决呢?

想想强制类型转换,为什么能转换成功呢?这就为实现继承做了基础,加上前面有几篇写过可执行文件的结构,将在后面给出一种方式。

1.一个简单的类

#include<stdio.h>
#include<stdlib.h>

typedef struct Man {

	int age;
	void (*sayHi)();
}Man;

void manSayHi(){
	printf("hi ... \n");
}

Man* createMan(){
	return (Man*)malloc(sizeof(Man));
}

void deleteMan(Man* m){
	free(m);
}

Man* initMan(Man* m,int age){

	m->age = age;
	m->sayHi = manSayHi;
	return m;
}

int main(){

	int a;
	Man* m = initMan(createMan(),30);
	m->sayHi();
	printf("man age = %d \n",m->age);
	deleteMan(m);

        //这里只是让弹出的命令窗口,等待一个数值,不消失。
	scanf_s("%d",&a);
}


在结构体Man中,age相当于一个成员变量,sayHi是一个函数指针,相当于一个成员方法。

有一点需要说明,在createMan函数中,malloc函数返回的是一个void* 的指针,在这里强制类型转换成了一个 Man* 的指针,这是在VS2012 中。

在Mac下Xcode中不需要强转。

C语言中,void* 本身可以指向任意类型的指针,VS的语法检查是否过于严格了呢。


对一个类来讲,有构造 和 析构 两部,我们这里对应的构造是分成了两步:

①分配内存 createMan

②初始化 initMan

析构只有一步:

释放内存deleteMan

运行结果:


2.类的继承

提到类的继承,想想父类与子类的关系,子类可以向父类转型,这一点跟强制类型转换是否很相似?

那么只要在链接成的可执行文件中,将子类与父类的内容按顺序排放,就实现了一个继承的关系。

#include<stdio.h>
#include<stdlib.h>

#define Obj_Field void (*onDestroy)();

#define createObj(Type) malloc(sizeof(Type))

#define deleteObj(Type)\
{\
	Type->onDestroy();\
	free(Type);\
}

typedef struct Object{
	Obj_Field
}Object;


Object* initObj(void* obj){
	printf("obj init ... \n");
}
 

typedef struct Man {

	Obj_Field
	int age;
	void (*sayHi)();
}Man;

void manSayHi(){
	printf("hi ... \n");
}

void manOnDestroy(){
	printf("man on destroy ... \n");
}

Man* initMan(Man* m,int age){

	m->age = age;
	m->sayHi = manSayHi;
	m->onDestroy = manOnDestroy;

	printf("man init ... \n");

	return m;
}

int main(){

	int a;
	Man* m = initMan((Man*)createObj(Man),30);
	m->sayHi();
	printf("man age = %d \n",m->age);
	deleteObj(m);


	scanf_s("%d",&a);
}

先看运行结果:

在这里只要把 Obj_Field 这个宏放在 Man的最开始的位置上,就可以实现 继承的关系了,即使向 Object转型,也不会因截断而出错。

这是声明Obj_Field 这个宏的原因。

创建对象也用了一个宏,是为什么呢?

因为一个子类所占用的空间往往比父类的要大,所以要动态的为子类非配空间,具体的类型还未确定。

需要等到真正执行程序的时候才去决定。

那么销毁对象的方式也就与此想通了。

这里依然如此,malloc分配返回的void* 要强转成具体类型。(Windows VS2012下,Mac Xcode不需要)

Man* m = initMan((Man*)createObj(Man),30);


这样,一个简单的继承就实现了。

 

© 著作权归作者所有

谁染霜林醉
粉丝 3
博文 15
码字总数 18432
作品 0
济南
程序员
私信 提问
C语言大型软件设计的面向对象-宋宝华-专题视频课程

C语言大型软件设计的面向对象—369人已学习 课程介绍 C语言代码一旦达到一定规模,就特别强调良好的架构设计,以保证代码的可读性好、代码简洁以及可复用。此时,软件设计师势必要用C语言来做...

21cnbao
2017/11/17
0
0
C/C++,最经典的编程语言.

1、从C到C++ 计算机诞生初期,用机器语言或汇编语言编写程序; 第一种高级语言FORTRAN诞生于1954年; BASIC语言(1964)是由FORTRAN语言的简化而成的是为初学者设计的小型高级语言; C语言是1972年...

小辉灰520
2018/11/26
0
0
一、C语言概述

说明:这个C语言专题,是学习iOS开发的前奏。也为了让有面向对象语言开发经验的程序员,能够快速上手C语言。如果你还没有编程经验,或者对C语言、iOS开发不感兴趣,请忽略 为什么iOS开发要先...

长平狐
2013/03/28
175
1
Object-C基础-01-概述

回到顶部 前言 目前来说,Objective-C(简称OC)是iOS开发的核心语言,在开发过程中也会配合着使用C语言、C++,OC主要负责UI界面,C语言、C++可用于图形处理。近来,流传Ruby、C#也可以开发iOS...

Corwien
2016/03/16
41
0
面向对象的设计思想

博主之间是做 Linux C++ 软件开发的,深刻地领悟到了面向对象的设计思想。但新的工作岗位是做嵌入式开发的,用的是C语言,突然有一点不太习惯。 C语言是一种面向过程的语言,它本身不像C++具...

临峰不畏
2015/09/04
265
0

没有更多内容

加载失败,请刷新页面

加载更多

前端面试题汇总

一. HTML常见的兼容性 1.HTML5 标签在低版本浏览器不兼容 解决办法:使用html5shiv库,引入下列语句 <!--[if lte IE 8]> <script src="https://cdn.bootcss.com/html5shiv/r29/html5.js"></sc......

蓝小驴
16分钟前
3
0
OSChina 周四乱弹 —— 我气的脸都黑了!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐《Red Battle》- 高橋李依 / 豊崎愛生 《Red Battle》- 高橋李依 / 豊崎愛生 手机党少年们想听歌,请使劲儿戳(这里) @丶Lion ...

小小编辑
29分钟前
367
17
找OSG教程, B站就有

https://www.bilibili.com/video/av64849038?from=search&seid=11632913960900279653

洛克人杰洛
50分钟前
4
0
学习记录(day07-Vue组件、自定义属性、自定义事件)

[TOC] 1.1.1什么是组件 一个vue文件就是一个组件 组件将html标签/css样式/对应JS打包成一个整体,也可以理解钻进一个具有样式和特效的自定义标签。 一、编写组件(提供方)<template> <di...

庭前云落
55分钟前
4
0
使用Prometheus监控SpringBoot应用

通过之前的文章我们使用Prometheus监控了应用服务器node_exporter,数据库mysqld_exporter,今天我们来监控一下你的应用。(本文以SpringBoot 2.1.9.RELEASE 作为监控目标) 编码 添加依赖 使...

JAVA日知录
57分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部