Chinaunix首页 | 论坛 | 博客
  • 博客访问: 191696
  • 博文数量: 28
  • 博客积分: 1490
  • 博客等级: 上尉
  • 技术积分: 310
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-17 10:01
文章分类
文章存档

2012年(3)

2011年(2)

2008年(2)

2007年(7)

2006年(14)

我的朋友

分类: C/C++

2006-10-23 21:50:29

Inside Object-Oriented Programming Using ANSI C
系列之二

一、 C 的继承。


/* flower.h */

#ifndef _FLOWER_H
#define _FLOWER_H

typedef struct _tag_Flower Flower;
struct _tag_Flower
{
    int color;
};

#endif



/* flower.c */

#include <stdio.h>
#include <assert.h>
#include "flower.h"


void
flower_set_color(Flower* self, int color)
{
    assert(self != NULL);
    self->color = color;
}

int
flower_get_color(Flower* self)
{
    assert(self != NULL);
    return self->color;
}

void
flower_blow(Flower* self)
{
    printf("listen, the flower's blowing voice ... \n");
}



现在,Rose 将继承自 Flower :


/* rose.h */

#ifndef _ROSE_H
#define _ROSE_H

#include "flower.h"

typedef struct _tag_Rose Rose;
struct _tag_Rose
{
    Flower flower; /* must be first */
   

    /* private */

    int thorn;
};

#endif



/* rose.c */

#include <stdio.h>
#include <assert.h>
#include "rose.h"

void
rose_set_thorn_nr(Rose* self, int thorn)
{
    assert(self != NULL);
    self->thorn = thorn;
}

int
rose_get_thorn_nr(Rose* self)
{
    assert(self != NULL);
    return self->thorn;
}

void
rose_blow(Rose* self)
{
    printf("listen, rose is blowing, and your lover is coming ... \n");

}


相应的测试程序如下:


/* demo.c */

#include <stdio.h>
#include <assert.h>
#include "rose.h"

int
main(int argc, char* argv[])
{
    Rose rose;
    Flower* flower = (Flower*) &rose;

    flower_set_color(flower, 255);
    printf("rose color :%d\n", rose.flower.color);
    printf("rose color: %d\n", flower_get_color(flower));

    rose_set_thorn_nr(&rose, 11);
    printf("rose has %d thorns.\n", rose_get_thorn_nr(&rose));

    printf("flower blow:\n");
    flower_blow(flower);
    printf("rose blow:\n");
    rose_blow(&rose);
    
    return 0;
}


在命令行编译:
$ gcc -o demo demo.c rose.c flower.c

运行:
$ ./demo

你可以看见输出的结果。可以体会一下。这里想强调的是在 struct Rose 的定义的时候,第一个元素必须是 Flower, 这样确保强制转换后正好和 Flower 相对应,这正是在开篇提到的 C 语言的特性所致。

二、 动态链接

动态链接以在运行时确定加载的模块,绝大多数流行的基于插件的项目都是以这种机制来实现的。

函数指针在这里扮演非常重要的角色。


/* test.c */


#include <stdio.h>

int
func_add(int a, int b)
{
    return (a + b);
}

int
func_multi(int a, int b)
{
    return (a * b);
}

int
main(int argc, char* argv[])
{

    int result = 0;


    if (argc != 3)
        goto usage;


    if (0 == strcmp("static", argv[1]))
    {
        if (argv[2][0] == '+')
           
result = func_add(11, 22);
        else if (argv[2][0]
== '*')
           
result = func_multi(11, 22);
        else
            goto usage;
    }
    else if (0 == strcmp("dynamic", argv[1]))
    {
        typedef int (*func)(int, int );
        func func_pointer;
        if ('+' == argv[2][0])
            func_pointer = func_add;
        else if ('*' == argv[2][0])
            func_pointer = func_multi;
        else
            goto usage;

        result = func_pointer(11, 22);
    }
    else
        goto usage;


    printf("result: \n", result);


    return 0;


usage:
    printf("usage: test [static|dynamic] [+|*]\n");
    return 1;
}


$ gcc -o test test.c

注意:测试乘法运算函数时,需要将 * 号转义。
$ ./test dynamic \*

动态链接让子类覆盖父类的同名函数成为可能。这将在后续的章节中详细讨论。
阅读(1477) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~