C++句柄类解析

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

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

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

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

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

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

①指针型句柄:

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

定义方案:

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

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

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

对于构造函数:

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

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

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

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

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

  1. class Item_base
  2. {
  3. public:
  4. virtual Item_base* clone() const
  5. {
  6. return new Item_base(*this);
  7. }
  8. };

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

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

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

  1. inline bool
  2. compare(const Sales_item &lhs, const Sales_item &rhs)
  3. {
  4. return lhs->book() < rhs->book();
  5. }

使用带关联容器的比较器

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

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

// 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)

C++句柄解析的更多相关文章

  1. (转)WINDOWS内核对象

    WINDOWS内核对象 原文地址:http://blog.csdn.net/misterliwei/article/details/976988  支持原创 一.前言 Windows中有很多像进程对象 ...

  2. 在C++中使用C#编写的类2

    在那篇<在C#中使用C++编写的类>中我介绍了如何在C#中使用C++编写的类.可是由于C#在用户界面设计.数据库存储和XML文件读取等方面的优势,有时候也会出现要在C++中使用C#编写的类 ...

  3. JDK8中JVM对类的初始化探讨

    在<深入理解Java虚拟机>(第二版,周志明著)中,作者介绍了JVM必须初始化类(或接口)的五种情况,但是是针对JDK7而言的. 那么,在JDK8中,这几种情况有没有变化呢?(我猜测应该会 ...

  4. JDK 8 - JVM 对类的初始化探讨

    在<深入理解 Java 虚拟机>(第二版,周志明著)中,作者介绍了 JVM 必须初始化类(或接口)的五种情况,但是是针对 JDK 7 而言的. 那么,在 JDK 8 中,这几种情况有没有变 ...

  5. C#与西门子PLC通讯

    1.0  通讯组件概述 通讯组件用于PC与可编程控制器(PLC).智能仪表等进行数据通讯,适用于基于PC高级语言的工业自动化控制系统.组件采用动态链接库文件(*.DLL)的形式,在PC系统的项目工程里 ...

  6. JVM解毒——类加载子系统

    带着问题,尤其是面试问题的学习才是最高效的.加油,奥利给! 点赞+收藏 就学会系列,文章收录在 GitHub JavaEgg ,N线互联网开发必备技能兵器谱 直击面试 看你简历写得熟悉JVM,那你说说 ...

  7. JVM详解之:类的加载链接和初始化

    目录 简介 加载 运行时常量池 类加载器 链接 验证 准备 解析 初始化 总结 简介 有了java class文件之后,为了让class文件转换成为JVM可以真正运行的结构,需要经历加载,链接和初始化 ...

  8. React-Native知识点相关

    React-Native相关 一,为什么要使用React-native? Hybrird的首屏时间太慢,白屏太久,影响用户体验: 原生native开发成本较高: 这里补充一点Webview的性能优化: ...

  9. JVM之类加载器子系统

    类加载器子系统 作用 负责从文件系统或网络系统中加载class文件,class文件在开头有特殊的标记(魔术开头CA FE BA BE) ClassLoader只负责加载class文件,至于能否运行,由 ...

随机推荐

  1. C#中的一些基础

    值类型与引用类型 值类型包括:[基本数据类型,如int,double,char,bool等][枚举类型enum][结构类型struct] 引用类型包括:[类类型,如基类Object,字符串类Strin ...

  2. tomcat配置内存

    windows: Create a new script named as setenv.bat under TOMCAT_HOME/bin folder holding the following ...

  3. 浅谈AC自动机

    写在前面:从10月23日开始写这篇博文,离NOIP2018只有十多天了.坚持不停课的倔强蒟蒻(我)尽量每天挤时间多搞一搞信竞(然而还要准备期中考试).NOIP争取考一个好成绩吧. 一.简介 AC自动机 ...

  4. 6、LwIP协议规范翻译——缓冲及内存管理

    6.缓冲及内存管理 在一个通信系统中,内存缓冲管理系统必须容纳各种大小的缓冲数据,其范围从包含具有数百个字节的数据的全尺寸TCP段到只有几个字节的短ICMP回复包.此外,为了避免拷贝,应该让数据内容缓 ...

  5. (3.1)mysql备份与恢复之mysqldump

    目录: 1.单实例联系 1.1.备份单个数据库联系多种参数使用 [1]mysqldump命令备份演示 [2]查看备份文件 [3]用备份文件还原 1.2.mysqldump 各类参数释义 [1]--de ...

  6. redis安装及错误排查

    安装: 1.cd /usr/redis   //redis目录作为安装目录,没有自行创建 2.tar xzf  redis-4.0.6.tar.gz 3. cd redis-4.0.6 4.make ...

  7. Spark实时案例

    1.概述 最近有同学问道,除了使用 Storm 充当实时计算的模型外,还有木有其他的方式来实现实时计算的业务.了解到,在使用 Storm 时,需要编写基于编程语言的代码.比如,要实现一个流水指标的统计 ...

  8. 用 python 生成一个简单的词云图

    import jieba from nltk import * from wordcloud import WordCloud import matplotlib.pyplot as plt word ...

  9. Why Choose MB SD C5 with Engineer Software

    MB SD C5 with engineer software performed good and now is released. Unlike the old clone C5 which us ...

  10. Scala--reduceLeft

    reduceLeft神语法 val a = Array(20, 12, 6, 15, 2, 9) 1 2 3 4 5 6 7 8 scala> a.reduceLeft(_ + _)  // 数 ...