C实现面向对象的继承

来源:互联网 发布:idea 10开发java web 编辑:程序博客网 时间:2024/05/22 15:41
  
听弦断,断那三千痴缠。
坠花湮,湮没一朝风涟。
花若怜,落在谁的指尖
时间最苦,剪不断对你的思恋
记忆最甜,抹弯嘴角的朱颜。
不知故人现在何方?不知红颜为谁而断?
捧一把月光,吹落簌簌哀伤。相盼相望,顾影自怜。
白衣起舞,玉指轻弹,买醉花酒前。梦回流年,微雨双飞燕。。。。。。 
其实很喜欢古文,因为意境很美,恬静、忧伤、凄迷、淡然,没有车水马龙,内心的平静,没有浮躁。
今天看了这个书的关于继承的这部分,就写点笔记噻

子类:(继承)

子类可以复用父类所有的设计和代码,

子类具有两大特点:

Specialize:

Note that specialization refers exclusively to changing the implementation of operations and not at all to the redefinition of data.

Extend:

the child class will have new features, such as new attributes or operations.

对于specialization: 可以使用上文中实现多态的switch-case条件判断,但是那种方法显得过于死板,也不是真正意义上的多态,我们有一种更灵活的方式来实现这一点-----函数指针

对于extension: 子类中包含父类的指针,于是子类的实例中就继承了父类所有的属性。

文中举了一个队列的例子,父类是Queue,派生出子类CachedQueue,见uml图表示:

 

 

我们来看一下具体实现代码:

父类:Queue

头文件Queue.h

#ifndef QUEUE_H_

#define QUEUE_H_

#define QUEUE_SIZE 10

/* class Queue */

typedef struct Queue Queue;

struct Queue {

int buffer[QUEUE_SIZE]; /* where the data things are */

int head;

int size;

int tail;

int (*isFull)(Queue* const me);

int (*isEmpty)(Queue* const me);

int (*getSize)(Queue* const me);

void (*insert)(Queue* const me, int k);

int (*remove)(Queue* const me);

//这些函数指针都是虚函数

};

/* Constructors and destructors:*/

void Queue_Init(Queue* const me,int (*isFullfunction)(Queue* const me),

int (*isEmptyfunction)(Queue* const me),

int (*getSizefunction)(Queue* const me),

void (*insertfunction)(Queue* const me, int k),

int (*removefunction)(Queue* const me) );

void Queue_Cleanup(Queue* const me);

//看起来实现的好复杂哦,是我见到的最长的初始化函数

/* Operations */

int Queue_isFull(Queue* const me);

int Queue_isEmpty(Queue* const me);

int Queue_getSize(Queue* const me);

void Queue_insert(Queue* const me, int k);

int Queue_remove(Queue* const me);

Queue * Queue_Create(void);

void Queue_Destroy(Queue* const me);

#endif /*QUEUE_H_*/

 

Queue 实现文件Queue.c

#include <stdio.h>

#include <stdlib.h>

#include "queue.h"

void Queue_Init(Queue* const me,int (*isFullfunction)(Queue* const me),

int (*isEmptyfunction)(Queue* const me),

int (*getSizefunction)(Queue* const me),

void (*insertfunction)(Queue* const me, int k),

int (*removefunction)(Queue* const me) ){

/* initialize attributes */

me->head = 0;

me->size = 0;

me->tail = 0;

/* initialize member function pointers */

me->isFull = isFullfunction;

me->isEmpty = isEmptyfunction;

me->getSize = getSizefunction;

me->insert = insertfunction;

me->remove = removefunction;

}

/* operation Cleanup() */

void Queue_Cleanup(Queue* const me) {

}

/* operation isFull() */

int Queue_isFull(Queue* const me){

return (me->head+1) % QUEUE_SIZE == me->tail;

}

/* operation isEmpty() */

int Queue_isEmpty(Queue* const me){

return (me->head == me->tail);

}

/* operation getSize() */

int Queue_getSize(Queue* const me) {

return me->size;

}

/* operation insert(int) */

void Queue_insert(Queue* const me, int k) {

if (!me->isFull(me)) {

me->buffer[me->head] = k;

me->head = (me->head+1) % QUEUE_SIZE;

++me->size;

}

}

/* operation remove */

int Queue_remove(Queue* const me) {

int value = -9999; /* sentinel value */

if (!me->isEmpty(me)) {

value = me->buffer[me->tail];

me->tail = (me->tail+1) % QUEUE_SIZE;

--me->size;

}

return value;

}

Queue * Queue_Create(void) {

Queue* me = (Queue *) malloc(sizeof(Queue));

if(me!=NULL)

{

Queue_Init(me, Queue_isFull, Queue_isEmpty, Queue_getSize,

Queue_insert, Queue_remove);

}

return me;

}

void Queue_Destroy(Queue* const me) {

if(me!=NULL)

{

Queue_Cleanup(me);

}

free(me);

}

测试程序:

#include <stdio.h>

#include <stdlib.h>

#include "queue.h"

int main(void) {

int j,k, h, t;

/* test normal queue */

Queue * myQ;

myQ = Queue_Create();

k = 1000;

for (j=0;j<QUEUE_SIZE;j++) {

h = myQ->head;

myQ->insert(myQ,k);

printf("inserting %d at position %d, size =%d\n",k--,h, myQ->getSize(myQ));

};

printf("Inserted %d elements\n",myQ->getSize(myQ));

for (j=0;j<QUEUE_SIZE;j++) {

t = myQ->tail;

k = myQ->remove(myQ);

printf("REMOVING %d at position %d, size =%d\n",k,t, myQ->getSize(myQ);

};

printf("Last item removed = %d\n", k);

printf("Current queue size %d\n", myQ->getSize(myQ));

puts("Queue test program");

return EXIT_SUCCESS;

}

 

子类CachedQueue

CachedQueue.h文件

#ifndef CACHEDQUEUE_H_

#define CACHEDQUEUE_H_

#include "queue.h"

typedef struct CachedQueue CachedQueue;

struct CachedQueue {

Queue* queue; /* base class */

/* new attributes */

char filename[80];

int numberElementsOnDisk;

/* aggregation in subclass */

Queue* outputQueue;

/* inherited virtual functions */

int (*isFull)(CachedQueue* const me);

int (*isEmpty)(CachedQueue* const me);

int (*getSize)(CachedQueue* const me);

void (*insert)(CachedQueue* const me, int k);

int (*remove)(CachedQueue* const me);

/* new virtual functions */

void (*flush)(CachedQueue* const me);

void (*load)(CachedQueue* const me);

};

/* Constructors and destructors:*/

void CachedQueue_Init(CachedQueue* const me, char* fName,

int (*isFullfunction)(CachedQueue* const me),

int (*isEmptyfunction)(CachedQueue* const me),

int (*getSizefunction)(CachedQueue* const me),

void (*insertfunction)(CachedQueue* const me, int k),

int (*removefunction)(CachedQueue* const me),

void (*flushfunction)(CachedQueue* const me),

void (*loadfunction)(CachedQueue* const me));

void CachedQueue_Cleanup(CachedQueue* const me);

/* Operations */

int CachedQueue_isFull(CachedQueue* const me);

int CachedQueue_isEmpty(CachedQueue* const me);

int CachedQueue_getSize(CachedQueue* const me);

void CachedQueue_insert(CachedQueue* const me, int k);

int CachedQueue_remove(CachedQueue* const me);

void CachedQueue_flush(CachedQueue* const me);

void CachedQueue_load(CachedQueue* const me);

CachedQueue * CachedQueue_Create(void);

void CachedQueue_Destroy(Ca CachedQueue* const me);

#endif /*CACHEDQUEUE_H_*/

 

CachedQueue.c文件

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "cachedQueue.h"

void CachedQueue_Init(CachedQueue* const me, char* fName,

int (*isFullfunction)(CachedQueue* const me),

int (*isEmptyfunction)(CachedQueue* const me),

int (*getSizefunction)(CachedQueue* const me),

void (*insertfunction)(CachedQueue* const me, int k),

int (*removefunction)(CachedQueue* const me),

void (*flushfunction)(CachedQueue* const me),

void (*loadfunction)(CachedQueue* const me)) {

/* initialize base class */

me->queue = Queue_Create(); /* queue member must use its original functions */

/* initialize subclass attributes */

me->numberElementsOnDisk = 0;

strcpy(me->filename, fName);

/* initialize aggregates */

me->outputQueue = Queue_Create();

/* initialize subclass virtual operations ptrs */

me->isFull = isFullfunction;

me->isEmpty = isEmptyfunction;

me->getSize = getSizefunction;

me->insert = insertfunction;

me->remove = removefunction;

me->flush = flushfunction;

me->load = loadfunction;

}

/* operation Cleanup() */

void CachedQueue_Cleanup(CachedQueue* const me) {

Queue_Cleanup(me->queue);

}

/* operation isFull() */

int CachedQueue_isFull(CachedQueue* const me){

return me->queue->isFull(me->queue) &&

me->outputQueue->isFull(me->outputQueue);

}

/* operation isEmpty() */

int CachedQueue_isEmpty(CachedQueue* const me){

return me->queue->isEmpty(me->queue) &&

me->outputQueue->isEmpty(me->outputQueue) &&

(me->numberElementsOnDisk == 0);

}

/* operation getSize() */

int CachedQueue_getSize(CachedQueue* const me) {

return me->queue->getSize(me->queue) +

me->outputQueue->getSize(me->outputQueue) +

me->numberElementsOnDisk;

}

/* operation insert(int) */

// Imsert Algorithm:

// if the queue is full,

// call flush to write out the queue to disk and reset the queue

// end if

// insert the data into the queue

void CachedQueue_insert(CachedQueue* const me, int k) {

if (me->queue->isFull(me->queue)) me->flush(me);

me->queue->insert(me->queue, k);

}

/* operation remove */

// remove algorithm

// if there is data in the outputQueue,

// remove it from the outputQueue

// else if there is data on disk

// call load to bring it into the outputQueue

// remove it from the outputQueue

// else if there is data in the queue

// remove it from there

// (if there is no data to remove then return sentinel value)

int CachedQueue_remove(CachedQueue* const me) {

if (!me->outputQueue->isEmpty(me->outputQueue))

return me->outputQueue->remove(me->outputQueue);

else if (me->numberElementsOnDisk>0) {

me->load(me);

return me->queue->remove(me->queue);

}

else

return me->queue->remove(me->queue);

}

/* operation flush */

// Precondition: this is called only when queue is full

// and filename is valid

// flush algorithm

// if file is not open, then open file

// while not queue->isEmpty()

// queue->remove()

// write data to disk

// numberElementsOnDisk++

// end while

void CachedQueue_flush(CachedQueue* const me){

// write file I/O statements here . . .

}

/* operation load */

// Precondition: this is called only when outputQueue is empty

// and filename is valid

// load algorithm

// while (!outputQueue->isFull() && (numberElementsOnDisk>0)

// read from start of file (i.e., oldest datum)

// numberElementsOnDisk– –;

// outputQueue->insert()

// end while

void CachedQueue_load(CachedQueue* const me) {

// write file I/O statements here . . .

}

CachedQueue * CachedQueue_Create(void) {

CachedQueue* me = (CachedQueue *)

malloc(sizeof(CachedQueue));

if(me!=NULL)

{

CachedQueue_Init(me, "C:\\queuebuffer.dat",

CachedQueue_isFull, CachedQueue_isEmpty, CachedQueue_getSize, CachedQueue_insert, CachedQueue_remove,

CachedQueue_flush, CachedQueue_load);

}

return me;

}

void CachedQueue_Destroy(CachedQueue* const me) {

if(me!=NULL)

{

CachedQueue_Cleanup(me);

}

free(me);

}

 

好冗长的代码喲,C++轻而易举实现的事情,C却费了好一番周折。也许真的没有必要这么做,但是即便如此,我还是想把这本书看完

不因为别的,就因为想看完

原创粉丝点击