从开源项目学到的编程技巧

最直接的学习方式就是RTFSC


1.  OOC 之 OVERRIDE --- 使用函数指针实现重载和代码重用机制.

假设我需要编写库接口 do_something    但是我只能明确这个接口的通用功能, 可能不同

工程会有些自己的定制需求. 于是我就这样实现:


void (*do_something)(void);
void do_something_default(void)
{
      // Lots of common job
}

do_something = do_something_default;

这样如果用户不需要特殊定制, 就直接调用这个接口 

do_something();

如果他需要特殊定制的话, 就向下面这个操作:

void (*original_do) (void) = NULL;

void do_special_job(void)
{
    original_do();
    //Special jobs
   // ...
}

void func_hook()
{
    if(!original_do)
    {
        original_do = do_something;        
    }
    do_something = do_special_job;
}

然后在使用 do_something 之前先调用 HOOK 函数 func_hook , 就成功的重载了,而且之前的代码也很好的复用了 .

最后, 这个过程还可以重复的!  C 重载 B  ,  B 重载 A . 没有问题.


2. 使用构造函数实现添加链表节点 , 实现自由定制工厂类

假设我们有个工厂类 Factory, 可以生产各种 Item 类的子类, 但是我们不知道 Item 类到底会有多少子类 , 于是我们让 Factory 维护一个链表,

每个节点上有一个生产Item 特定子类类的接口.每一个Item子类都自己设计自己的节点 . 这样Factory 只需要每次遍历链表,根据参数选出对

应的节点来生产Item子类就可以了.

问题是我不希望在main函数中开始专门加入一个 init_list 来一一添加所有的Item子类的节点 ,这样容易遗漏 , 而且每次添加新的Item子类都

要来修改这个接口, 我希望新的Item 子类自行将生产节点添加到链表中

例子:

// Factory.h
struct Node
{
     Node( Item*(*f)() , Node * n) : Item_creator(f) , next(n) {}
     Item * (* Item_creator)();
     Node * next; 
};

class Factory 
{
    public :
        static void addNode(  Node *);
    private :
         static Node * head;
};

class ListAddr
{
    public:
        ListAddr(Node *n){ Factory::addNode(n);}
};

//Item.h
class Item
{
 // ...
};
class A : public Item
{
    public:
        Item * A_creator();
    // ...
};
// item.cpp

Node A_Node( A::A_creator , 0 );
ListAddr A_adder(&A_Node); 


这样在main函数开始之前, 链表就已经构造好了, main函数不需要在考虑它了.

而且添加Item子类需要修改的文件也少了 , 也不容易遗漏了 .


3. 使用宏来减少重复工作 .

还是用上面的例子, 每次添加一个Item 子类 , 都需要定义他的Node 和 ListAddr , 这是很烦人的.  下面的宏可以节约时间


#define NODEADDER(class_name, func ) \
Node class_name_##node(func,0);\
ListAddr class_name##adder(&class_name_##node);
 
添加子类节点的时候:

NODEADDER(A, A::A_creator)

是不是简洁了很多!


4. 使用函数调用实现继承和派生的和谐存在


C++为我们提供了继承和派生, 但是如果我想要在原有的基础上添加新的操作呢 ? 

简单的实现是这样的:

class Father
{
     public: 
        virtual void InterfaceA()
        {
         //TODO :
        }
};
class Child : public Father 
{
     public:
        virtual void InterfaceA()
        {
             Father::InterfaceA();
             //TODO : somethine else
        }
}

这样子每一个子类都要写

          Father::InterfaceA();


为了减少这部分工作量, 也减少忘记写导致BUG的可能性, 可以这样


class Father
{
     public: 
        void InterfaceA()
        {
            // TODO Common stuff
             SelfInterfaceA();
        }
        virtual void SelfInterfaceA() = 0;
     
};
class Child : public Father 
{
     public:
        vitrual void SelfInterfaceA()
        {
             //TODO : somethine else
        }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值