C与C++在OO面向对象实现上的对比

1.  Factory Method工厂方法

        C和C++的工厂的对比,可以看出C的面向"过程"设计和C++面向"对象"设计的明显差异

        在log4c中,category(等同logger)/appender/layout是通过统一的sd_factory_**提供Service Design接口


static constsd_factory_ops_t log4c_category_factory_ops = {

(void*)log4c_category_new,

(void*)log4c_category_delete,

(void*)log4c_category_print,

};

///

struct __sd_factory

{

  char*         fac_name;

  const sd_factory_ops_t*   fac_ops;

  sd_hash_t*            fac_hash;

};

///

全局log4c_category_factory为

{

    “log4c_category_factory”;

    &log4c_category_factory_ops;

    ...

}

        (1)log4c_category_factory和log4c_appender_factory和log4c_layout_factory是单态的工厂,通过sd_factory_xx来做管理,维护一个实例name到实例的映射

        log4cplus中AppenderFactory和LayoutFactory(AppenderFactoryRegistry,LayoutFactoryRegistry也是单态的)是通过FactoryRegistry来管理的,不管是C还是C++,他们都和设计模式无关,不管是Factory Method还是Abstract Factory都需要做工厂Factory管理的,维护一个实例name到实例的映射

        (2)在factory_ops中是否可以直接面对实例,比如category的type只有一种的,factory_ops直接面向实例的;而appender的type有constappender、fileappender等;需要多态实现才到达实例,descriptor中construct就是子类的实例化

        在log4cplus中,不一样的是子类实例在一开始就可以到达;相同的是logger的type只有一种,DefaultLoggerFactory就可以直接new一个catogery

        appender的type是多样的,需要用到Factory Method模式,ConsoleFactory可以直接new一个consoleappender,FileAppenderFactory可以直接new一个fileappender

        主要代码如下:

LoggerFactory(类函数makeNewLoggerInstance纯虚)一个默认子类

<----DefaultLoggerFactory

 

AppenderFactory(类函数createObject纯虚)N多子类

<----ConsoleFactory

<----FileAppenderFactory

......

           

LoggerDefaultLoggerFactory::makeNewLoggerInstance(const log4cplus::tstring& name,Hierarchy& h)

{

    return Logger( new spi::LoggerImpl(name, h));

}

SharedAppenderPtrConsoleAppenderFactory::createObject(const Properties& props)

{

    return SharedAppenderPtr(newlog4cplus::ConsoleAppender(props));

}  

       

2.  GC机制

        GC这一点C是很少会用的,网上很多在C上的GC实现机制,比如manualgc,实际上在用C编码的过程中就已经对内存使用预先设计好的,内存自动管理大可不必

        C++书中讲

构造函数:一般在定义类对象时自动运行.

析构函数:如果一个函数中定义了一个对象,则在这个函数运行结束时就执行一次;当一个对象是使用NEW运算符被动态创建的,在使用DELETE运算符释放它时,DELETE将会自动调用析构函数.

        依然和C一样需要手工管理,在C++上比较普遍的是采用智能指针和引用计数来做资源的自动化管理

        (1)在log4c中一个appender挂接到N个category,只需要把appender的指针指向不同category结构中cat_appender成员即可,至于内存释放的顺序,必须有coder来维护free,coder完全掌控内存管理

        (2)如果是在log4cplus中,这种情况下,每个appender在new的时候都会是一个引用计数指针,只有当所有挂接此appender的logger都不再引用的时候,appender才会释放,这就做到了资源的自动管理,C和C++对比区别非常的明显

        (3)appender挂接到logger的时候,对于C来说只要指针操作即可,如果一个logger有几个appender,用链表或者hash来管理

        (4)但是在C++中实现是新建一个类appenderattachable来管理的,比如addAppender,getAppender等等,用一个容器typedef std::vector<SharedAppenderPtr> ListType;来管理挂接的不同Appender,如图 


3.  Singleton

        在C中,所有初始化都会有一个明确的指示,何时初始化由coder来决定,但是在C++中有一种单态模式的静态对象,比如log4cplus中的

class_static_log4cplus_initializer {

public:

    _static_log4cplus_initializer() {

        log4cplus::initializeLog4cplus();

    }

} static staticinitializer;

        你都不知道他是何时初始化的,因为C++的静态对象的初始化顺序时编译是决定的,而且这种代码读起来太吃力了,很多人说:对于单件的处理,采用静态对象和惰性初始化的方案,简直就是 C++ 程序员的陋习。他们建议:静态对象的初始化放在相关的类中,所有的“全局”作用的对象,全部都延迟到main函数里面,作为main函数的局部变量来做

        比如如下:

SharedObjectPtr<LogLog>LogLog::getLogLog()

{

    static SharedObjectPtr<LogLog>singleton(new LogLog());

    return singleton;

}

        但是很多时候又需要这种静态对象的方式,比如通信产品中的TABLE表项的自动化生成的,如果手动去初始化,需要修改入口INIT代码,N的话,就非常的麻烦,如果采用静态对象,问题就解决了,程序会自动做初始化的


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值