zoukankan      html  css  js  c++  java
  • C++句柄解析

    C++句柄类解析

      引题:在C++中,对于运行时类型识别问题。在程序中使用引用或者指针在运行时动态识别对象类型。然而使用指针或者引用却增加了用户负担(在继承体系中,没有明确的基类到派生类的转换,必须用户显示转换并将结果对象加入容器中。但是这样的做法结果却是派生对象部分成员是未初始化的)。

    对于这一问题,可以将对象指针 保存在容器中来解决。但此时,用户必须明确容器中指针和 对象的同步性(不能只有指针而对象不存在或者收指针不存在,对象存在)。

    更好的解决方案就是句柄类了:

      C++ 中一个通用的技术是定义包装(cover)类或句柄类。句柄类存储和管 理基类指针。指针所指对象的类型可以变化,它既可以指向基类类型对象又可以 指向派生类型对象。用户通过句柄类访问继承层次的操作。因为句柄类使用指针 执行操作,虚成员的行为将在运行时根据句柄实际绑定的对象的类型而变化。因 此,句柄的用户可以获得动态行为但无须操心指针的管理。

      包装了继承层次的句柄有两个重要的设计考虑因素:

    • 对任何保存指针的类一样,必须确定对复制控制做些什 么。包装了继承层次的句柄通常表现得像一个智能指针 或者像一个值。
    • 句柄类决定句柄接口屏蔽还是不屏蔽继承层次,如果不屏蔽继承层次,用 户必须了解和使用基本层次中的对象。

    ①指针型句柄:

      句柄包装指针,用户可以将该句柄类当作指针使用,却不用去管理指针指向的对象。(句柄类更像是一个中介控制者)

    定义方案:

    1. 使用类包装指针,包装计数器(每个对象都有各自的这两个成员)

    2.使用类包装指针,包装计数器指针(资源和计数器共享)

    句柄类除了定义构造,拷贝构造,赋值,还需要定义引用,解引用(使之看起来更像是指针)

    对于构造函数:

    1个默认构造函数初始化成员为0;

    1个构造函数声明指定对象类型的句柄。

    那么问题来了,如果用户并不知晓用 继承体系中具体哪个层次对象进行初始化,如何做呢。

    解决这个问题的通用方法是定义虚操作进行复制,我们称将 该操作命名为 clone。(克隆):

      对于继承层次中的每个类,增加一个虚克隆函数eg:

    class Item_base 
    {
     public: 
        virtual Item_base* clone() const 
        { 
            return new Item_base(*this);
         }
     };    

    有了克隆函数那么 句柄类的定义如下:

    Sales_item::Sales_item(const Item_base &item):
        p(item.clone()), use(new std::size_t(1)) 
    { }

    对于继承层次中  如果需要逻辑比较函数,一个好的做法是 定义内部比较,比较内部核心成员。

    inline bool
    compare(const Sales_item &lhs, const Sales_item &rhs)
    {
        return lhs->book() < rhs->book();
    }

    使用带关联容器的比较器

    要有效地工作,关联容器需要对每个操作使用同一比较函数。然而,期望用 户每次记住比较函数是不合理的,尤其是,没有办法检查每个调用使用同一比较 函数。因此,容器记住比较函数是有意义的。通过将比较器存储在容器对象中, 可以保证比较元素的每个操作将一致地进行。

    这种做法,实质上就是使用函数指针,函数回调实现真正的比较。

    // type of the comparison function used to order the multiset

    typedef bool (*Comp)(const Sales_item&, const Sales_item&);

    关联容器的每个构造函数使我们能够提供比较函数的名 字。可以这样定义使用 compare 函数的空 multiset:

    std::multiset<Sales_item, Comp>  items(compare);

    multiset 是STL中的联合容器。。在头文件<set>中,具体用法请参看《STL源码剖析》

    参考(C++primer)

  • 相关阅读:
    链表
    Python中安装Requests库
    在vs中使用python
    CentOS添加windows引导
    c#创建windows服务
    SQLServer查询结果另存为csv格式中文乱码问题
    用svn管理GitHub项目
    Jquery操作select
    sqlserver2016安装
    信号处理函数陷阱:调用malloc导致死锁[转]
  • 原文地址:https://www.cnblogs.com/lang5230/p/5060574.html
Copyright © 2011-2022 走看看