用一个实例来对比函数指针(纯C写…

    C++的多态本质也是由函数指针来实现的。一般来说:写得好的多态比函数指针易于理解和维护,代码也比较简洁。
    用一个例子来来说明吧,下面用C++和C分别实现了两个管道框架,每个管道就是对输入处理一下,传给下一个管道(如果有的话)。
=======================================pipe.cpp=======================================
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

class Pipe
{
public:
    Pipe()
        : next(NULL)
    {
    }
    virtual ~Pipe(){} // 军规:基类必须有虚析构函数
    virtual void setNext(Pipe* next_)
    {
        assert(next == NULL && next_ != NULL);
        next = next_;       
    }
    virtual void push(int val)
    {
        int new_val = process(val);
        if (next)
        {
            next->push(new_val);
        }
    }
protected:
    Pipe* next;   
    virtual int process(int val) = 0;
};

class AddPipe
    : public Pipe
{
public:
    AddPipe(int num_)
        : num(num_)
    {
    }
    virtual int process(int val)
    {
        return (val + num);
    }
private:
    int num;
};

class MultiPipe
    : public Pipe
{
public:
    MultiPipe(int factor_)
        : Pipe()
        , factor(factor_)
    {
    }
    virtual int process(int val)
    {
        return (val * factor);
    }
private:
    int factor;
};

class PrintPipe
    : public Pipe
{
public:   
    virtual int process(int val)
    {
        printf("val = %d\n", val);
        return val;
    }
};

int main()
{
    AddPipe first(1);
    MultiPipe second(2);
    AddPipe third(10);
    PrintPipe last;
    first.setNext(&second);
    second.setNext(&third);
    third.setNext(&last);

    Pipe* pipe(&first);
    pipe->push(1);
    pipe->push(2);
    pipe->push(3);

    return 0;
}
    挺简单的吧,用C实现也不难
====================================pipe.c==========================================
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int (*PipeProcessor)(void* args, int val);

typedef struct Pipe
{
    struct Pipe* next;
    PipeProcessor handler;
    void* args;
} Pipe;

void init(Pipe* pipe)
{
    pipe->next = NULL;
    pipe->handler = NULL;
    pipe->args = NULL;
}
void process(Pipe* first, int val)
{
    Pipe* it = first;
    while (it != NULL)
    {
        val = (*(it->handler))(it->args, val);
        it = it->next;
    }
}
void attach(Pipe* front, Pipe* next)
{
    front->next = next;
}
int printPipe(void* args, int val)
{
    printf("val = %d\n", val);
    return val;
}
int addPipe(void* args, int val)
{
    return (*(int*)(args)) + val;
}
int multiPipe(void* args, int val)
{
    return (*(int*)(args)) * val;
}

int main()
{
    Pipe first;
    int first_args = 1;
    Pipe second;
    int second_args = 2;
    Pipe third;
    int third_args = 10;
    Pipe last;
   
    init(&first);   
    first.handler = addPipe;
    first.args = &first_args;
   
    init(&second);
    second.handler = multiPipe;
    second.args = &second_args;
    attach(&first, &second);
   
    init(&third);   
    third.handler = addPipe;
    third.args = &third_args;
    attach(&second, &third);

    init(&last);
    last.handler = printPipe;
    attach(&third, &last);
   
    process(&first, 1);
    process(&first, 2);
    process(&first, 3);

    return 0;
}
=========================================================================
    第一个实现不是使用接口继承,使用接口继承的实现如下
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

class Processor
{
public:
    virtual ~Processor(){}    // 军规,不解释
    virtual int process(int val) = 0;
};

class Pipe
{
public:
    Pipe(Processor* handler_)
        : handler(handler_)
        , next(NULL)
    {
    
    void setNext(Pipe* next_)
    {
        assert(next == NULL && next_ != NULL);
        next = next_;      
    }
    void push(int val)
    {
        int new_val = handler->process(val);
        if (next)
        {
            next->push(new_val);
        }
    }
private:
    Processor* handler;
    Pipe* next;  
};

class AddPipeProcessor
    : public Processor
{
public:
    AddPipeProcessor(int num_)
        : num(num_)
    {
    }
    virtual int process(int val)
    {
        return (val + num);
    }
private:
    int num;
};

class MultiPipeProcessor
    : public Processor
{
public:
    MultiPipeProcessor(int factor_)
        : factor(factor_)
    {
    }
    virtual int process(int val)
    {
        return (val * factor);
    }
private:
    int factor;
};

class PrintPipeProcessor
    : public Processor
{
public:  
    virtual int process(int val)
    {
        printf("val = %d\n", val);
        return val;
    }
};

int main()
{
    AddPipeProcessor add1(1);
    Pipe first(&add1);
    MultiPipeProcessor multi2(2);
    Pipe second(&multi2);
    AddPipeProcessor add10(10);
    Pipe third(&add10);
    PrintPipeProcessor print;
    Pipe last(&print);
    first.setNext(&second);
    second.setNext(&third);
    third.setNext(&last);

    first.push(1);
    first.push(2);
    first.push(3);

    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值