C语言面向对象风格编程
前言
本文略谈C面向对象风格编程,如何使用过程式语言去模拟面向对象的特性?C面向对象的方式和形式很多,不一而足,本文的代码形式是模拟部分C++面向对象关键词并赋予其特性,这种方式对于初级程序员比较好理解。但是要明确的是,只要使用OO思想编写程序,那么写出的就是面向对象代码,比如Linux C。面向对象语言如C++,Java则是在编译器层面为语言做了那部分工作,所以使用过程式语言则需要通过写代码手动完成那部分工作。
面向对象简述
面向对象具备3大特性:封装、继承和多态。大多数语言都具有封装特性,只不过面向对象在封装上进一步增强,并且将数据和方法进行糅合。在面向对象中顶级存在是类和对象,而在过程式语言中函数则是顶级存在。
上代码和示例
Object.h是所有类需要包含的,Person.h里面有人类示例,ObjectStyleCoding.cpp是C语言面向对象示例。本文旨在抛砖引玉。并未实现继承和多态因为其比较复杂,但其思想是结构指针、查表和判断。
Object.h:
1 #include<stdlib.h> 2 #ifdef Cplusplus_H 3 namespace ObjectStyleCLang{ 4 #else 5 extern "C"{ 6 #endif 7 8 #ifndef Object_Header_H 9 #define Object_Header_H 10 //boolean define 11 #define TRUE 1 12 #define FLASE 0 13 14 //class key words define 15 #define Public 16 #define Private static 17 #define ClassStatement(ClassName) struct ClassName 18 #define Class(ClassName) struct ClassName 19 #define ClassInnerPointer(ClassName) Class(ClassName)*ObjectThis 20 //memory define 21 #define NewArray(type,size) ((type*)malloc(sizeof(type)*size)) 22 #define New(type) NewArray(type,1) 23 #define Delete(memory) free(memory) 24 25 void ObjectCopy(unsigned char*,unsigned char*,unsigned int); 26 void ObjectCopy(unsigned char* dst,unsigned char* src,unsigned int Len) 27 { 28 unsigned int i=0; 29 for(;i<Len;i++){ 30 dst[i]=src[i]; 31 } 32 } 33 34 void StrCopy(char*dst,const char*src) 35 { 36 while (*src) 37 *dst++=*src++; 38 } 39 40 #endif 41 42 #ifdef Cplusplus_H 43 } 44 #else 45 } 46 #endif
Person.h:
1 #include "stdafx.h" 2 #include "Object.h" 3 4 #ifdef Cplusplus_H 5 namespace ObjectStyleCLang{ 6 #else 7 extern "C"{ 8 #endif 9 10 #ifndef Person_Header_H 11 #define Person_Header_H 12 13 14 ClassStatement(Person); 15 Public void Person_constructor(Class(Person)*); 16 Public void setage(Class(Person)*,int); 17 Public int getage(Class(Person)*); 18 Public void setname(Class(Person)*,char*); 19 Public char* getname(Class(Person)*self); 20 21 Class(Person){ 22 //Class data 23 ClassInnerPointer(Person); 24 //Class data 25 Public int age; 26 Public char name[255]; 27 //method 28 Public void (*setAge)(Class(Person)*,int); 29 Public int (*getAge)(Class(Person)*); 30 Public void (*setName)(Class(Person)*,char*); 31 Public char* (*getName)(Class(Person)*); 32 }; 33 34 35 Public void Person_constructor(Class(Person)*self) 36 { 37 self->ObjectThis=self; 38 self->getAge=getage; 39 self->setAge=setage; 40 self->getName=getname; 41 self->setName=setname; 42 self->age=self->name[0]=0; 43 } 44 45 Public void setage(Class(Person)*self,int age) 46 { 47 self->age=age; 48 } 49 Public int getage(Class(Person)*self) 50 { 51 return self->age; 52 } 53 Public void setname(Class(Person)*self,char* str) 54 { 55 StrCopy(self->name,str); 56 } 57 Public char* getname(Class(Person)*self) 58 { 59 unsigned char i=0; 60 char* name = NewArray(char,255); 61 while(self->name[i]){ 62 name[i]=self->name[i]; 63 i++; 64 } 65 name[i]='\0'; 66 return name; 67 } 68 69 #endif 70 71 #ifdef Cplusplus_H 72 } 73 #else 74 } 75 #endif
ObjectStyleCoding.cpp:
1 // ObjectStyleCoding.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include "Person.h" 6 #include<iostream> 7 8 int _tmain(int argc, _TCHAR* argv[]) 9 { 10 Class(Person) fang; 11 Person_constructor(&fang);//构造函数 12 fang.setAge(&fang,12); 13 fang.setName(&fang,"fang"); 14 std::cout<<fang.getName(&fang)<<std::endl; 15 return 0; 16 }