C/C++通用面向对象接口
来源:互联网 发布:网络投票怎么刷票软件 编辑:程序博客网 时间:2024/05/16 07:13
一,序
1,接口怎么做 自己在学习C/C++时的体会,如本文所述
2,什么是接口 实现一个功能的一组函数(或 方法)。
3,完美接口 与平台无关,与操作系统无关,甚至与语言无关;其他(例如:较少的接口函数,实现接口功能)略。
4,本文没有详尽的讲例子源码中(尤其是接口)每一个符号的含义,但实际上几乎每个符号都是有用意的。
5,如果C++部分,推荐两本书依次 <<C++ Primer>>、<<Inside C++ Object Model>>
6,本人以为,面向对象,只是一种效果;这种效果,C语言应该可以实现这个效果,不过可能会麻烦一点。
二,一般的 C 接口(面向对象的味道)
1,概述 得益于学习OpenSSL http://www.openssl.org;本文所讲的这种C语言接口还是比较基础,高手可以跳过;本人觉得这是种比较实用的接口方案。
2,接口原则 结构体打包接口使用到的所有数据;一般的,结构体指针作为接口函数第一个参数。
3,对外句柄 给调用者的可以不是结构体指针,可以是void*,这样可以把好多东西都做得透明。
4,借口扩展 新添接口函数就可以了。
5,比较经典的例子:zlib (http://www.zlib.net)。这是一个压缩的实现;压缩应该跟输入、输出无关;模式应该是"FilterInput"和"FilterOutput";z_stream数据结构,保存了所有和压缩有关的数据;所有"deflate"开头的接口函数,通过使用z_stream,实现了压缩功能;所有"inflate"开头接口函数,通过使用z_stream,实现了解压缩功能。
三,一般的 C++ 接口
1,原则 基类作接口,基类拥有所有接口方法,并且是虚的(virtual)。
2,原则 纯虚"空"基类。只有纯虚函数,没有构造函数,没有析构函数,没有数据成员。
3,实现 从接口基类派生,公有(public),非虚(non virtual);可多继承。
4,记得 额外多一个方法,用来摧毁对象;接口里面 “delete this;”就可以了。
5,调用 一定记得使用对象的 指针 或者 引用 调用。
6,接口扩展 从已有接口基类派生,公有(public),非虚(non virtual);增加新方法;单一继承,切记。
7,例子 微软COM,推荐:《Com本质论》;原理是C++的,并非微软的。
四,C / C++ 通用接口
1,虚函数表地址 C++对象可以这个东西的。就在这里做文章,就在这里,就在这里。
C++ 接口
1,虚函数表地址 接口基类,有且仅有这个东西。也就是说,没有数据成员,仅有纯虚方法,没有构造、析构方法。
2,有自我摧毁接口(例如:Destroy)
C++ 实现
1,从 接口基类 公有派生,实现所有方法,可以有数据成员。
2,自我摧毁接口 只是简单的执行“delete this”,具有虚析构函数。
C 接口
1,制作虚函数表 struct,依序包含函数指针,一一对应虚函数;每个函数参数增加一对象的指针作为参数第一项。
2,制作对象 struct,仅包含虚函数表地址
4,推荐 宏定义一下每一个操作。
C实现
1, 实现函数使用static修饰,避免冲突。
2,使用接口定义的虚函数表 不必重新定义类型,推荐定义这个结构体变量,给定初值。
3,具体对象结构体 函数表指针务必放在第一个位置,之后放数据成员。
另外
2,特殊的创建 C++不能用new了,因为new C不支持,自己写一个方法。
五,例子 (MIDemo)
C实现Tiger
C++实现Bear
C接口调用 TIger、Bear
C++接口调用 Tiger、Bear
Tiger用的是C,需要C版Animal接口;Bear用的是C++,需要C++版Animal接口;比较好的另一种解决办法是,各自做一个动态库,导出标准C函数符号。
MIC动态库:Tiger.c Animal.h Object.h mic.h mic.def
MICPP动态库:Bear.cpp Animal.hpp Bear.hpp Object.hpp MICPP.hpp MICPP.def
C接口
/* Object.h */
#ifndef __Object_h__
#define __Object_h__
typedef struct ObjectVFT_st ObjectVFT;
typedef struct Object_st Object;
struct ObjectVFT_st
{
void (* Destroy)(Object * This);
};
struct Object_st
{
ObjectVFT * pvft;
};
#define Object_Destroy(This) (This)->pvft->Destroy(This)
#endif
/* Animal.h */
#ifndef __Animal_h__
#define __Animal_h__
#include "Object.h"
typedef struct Animal_st Animal;
typedef struct AnimalVFT_st AnimalVFT;
struct AnimalVFT_st
{
void (* Destroy)(Animal * This);
void (* SayHello)(Animal * This, int n);
void (* SayHungry)(Animal * This, char * food);
};
struct Animal_st
{
AnimalVFT * pvft;
};
#define Animal_Destroy(This) Object_Destroy(This)
#define Animal_SayHello(This, n) (This)->pvft->SayHello(This, n)
#define Animal_SayHungry(This, food) (This)->pvft->SayHungry(This, food)
#endif
C++接口
/* Object.hpp */
#ifndef __Object_hpp__
#define __Object_hpp__
class Object
{
public:
virtual void Destroy(void) = 0;
};
#endif
/* Animal.hpp */
#ifndef __Animal_hpp__
#define __Animal_hpp__
#include "Object.hpp"
class Animal : public Object
{
public:
virtual void SayHello(int n) = 0;
virtual void SayHungry(char * food) = 0;
};
#endif
Tiger
/* Tiger.c */
#include <stdlib.h>
#include <stdio.h>
#include "Tiger.h"
#include "MIC.h"
static void _Destory(Animal * This);
static void _SayHello(Animal * This, int n);
static void _SayHungry(Animal * This, char * food);
static AnimalVFT g_TigerVFT = {_Destory, _SayHello, _SayHungry};
typedef struct Tiger_st
{
AnimalVFT * pvft;
int age;
char name[64];
}Tiger;
Animal * Tiger_new(void)
{
Tiger * pTiger = (Tiger*)malloc(sizeof(Tiger));
pTiger->pvft = & g_TigerVFT;
pTiger->age = 3;
sprintf(pTiger->name, "Tiger");
printf("/n malloc ... /n");
return (Animal*)pTiger;
}
static void _Destory(Animal * This)
{
printf("/n ha, just free./n");
free(This);
}
static void _SayHello(Animal * This, int n)
{
Tiger * pTiger = (Tiger*)This;
printf("/n %s hello %d /n", pTiger->name);
}
static void _SayHungry(Animal * This, char * food)
{
Tiger * pTiger = (Tiger*)This;
printf("/n %s want %s /n", pTiger->name, food);
}
Bear
/* Bear.hpp */
#ifndef __Bear_hpp__
#define __Bear_hpp__
#include "Animal.hpp"
class Bear : public Animal
{
private:
char _name[64];
public:
virtual void Destroy(void);
virtual void SayHello(int n);
virtual void SayHungry(char * food);
Bear();
virtual ~Bear();
};
#endif
/* Bear.cpp */
#include <iostream>
#include "Bear.hpp"
#include "MICPP.hpp"
Animal * Bear_new(void)
{
std::cout << std::endl << " new ..." << std::endl;
return new Bear;
}
Bear::Bear()
{
sprintf(_name, "Bear");
}
Bear::~Bear()
{
}
void Bear::Destroy(void)
{
std::cout << std::endl << " oh, delete this now." << std::endl;
delete this;
}
void Bear::SayHello(int n)
{
std::cout << std::endl << _name << " hello " << n << std::endl;
}
void Bear::SayHungry(char * food)
{
std::cout << std::endl << _name << " want " << food << std::endl;
}
C 创建对象
Tiger用的是C,需要C版的Animal;Bear用的是C++,需要C++版的Animal;
/* mic.h */
#ifndef __MIC_h__
#define __MIC_h__
#include "Animal.h"
#ifdef __cplusplus
extern "C" {
#endif
Animal * Tiger_new(void);
#ifdef __cplusplus
}
#endif
#endif
/* micpp.h */
#ifndef __MICPP_h__
#define __MICPP_h__
#include "Animal.h"
#ifdef __cplusplus
extern "C" {
#endif
Animal * Bear_new(void);
#ifdef __cplusplus
}
#endif
#endif
C++ 创建对象
/* mic.hpp */
#ifndef __MIC_hpp__
#define __MIC_hpp__
#include "Animal.hpp"
#ifdef __cplusplus
extern "C" {
#endif
Animal * Tiger_new(void);
#ifdef __cplusplus
}
#endif
#endif
/* MICPP.hpp */
#ifndef __MICPP_hpp__
#define __MICPP_hpp__
#include "Animal.hpp"
#ifdef __cplusplus
extern "C" {
#endif
Animal * Bear_new(void);
#ifdef __cplusplus
}
#endif
#endif
C 调用
#include "MIC.h"
#include "MICPP.h"
int main(int argc, char* argv[])
{
Animal * pBear = 0;
Animal * pTiger = 0;
pTiger = Tiger_new();
Animal_SayHello(pTiger, 3);
Animal_SayHungry(pTiger, "duck");
Object_Destroy(pTiger);
pBear = Bear_new();
Animal_SayHello(pBear, 3);
Animal_SayHungry(pBear, "duck");
Animal_Destroy(pBear);
return 0;
}
C++调用
#include "MIC.hpp"
#include "MICPP.hpp"
int main(int argc, char* argv[])
{
Animal * pTiger = Tiger_new();
pTiger->SayHello(3);
pTiger->SayHungry("duck");
Object * pObj = pTiger;
pObj->Destroy();
Animal * pBear = Bear_new();
pBear->SayHello(2);
pBear->SayHungry("fish");
pBear->Destroy();
return 0;
}
调用结果
MSVC 60 的执行结果。
malloc ...
Tiger hello 1245056
Tiger want duck
ha, just free.
new ...
Bear hello 3
Bear want duck
oh, delete this now.
六 小结
C调用的时候,那个Object_Destroy是不是有多态的味道??宏定义实现了C的多态?
- C/C++通用面向对象接口
- C语言面向对象编程(四):面向接口编程
- C语言面向对象编程(四):面向接口编程
- C语言面向对象编程(四):面向接口编程
- C语言面向对象编程之四:面向接口编程
- C/C++:C++面向对象
- C与面向对象
- C 面向对象程序设计
- c实现面向对象
- Obj-c面向对象
- JAVA面向对象C
- c面向对象设计
- c++-->面向对象
- 面向对象(C++)
- [C#] 面向对象
- c#-面向对象
- c实现面向对象
- c实现面向对象
- 一个简单的hibernate实例(之二)
- GNU Make 使用手册(中译版) 第2部分
- c语言的setjmp和longjmp
- javascript 汇总
- Java2游戏编程读书笔记第四章参考答案
- C/C++通用面向对象接口
- intelliFlow工作流系统可以支持复杂组织机构中的任务分派要求
- 当爱成为往事
- JavaScript技术讲座(一)——概况
- JavaScript技术讲座(二)——基本数据结构
- JavaScript技术讲座(三)——程序构成
- 第四讲 基于对象的JavaScript语言
- Context容器
- 第五讲 创建新对象