C++模板有很多特性需要我们去挖掘,很多新的设计模式也都与模板使用相关,我们知道模板的一个基本特性就是可以根据传入的类型产生新的类型。围绕这个特性,可以衍生出很多的其它特性,比如自动为不同的类生成static变量,为不同的类型生成不同的行为等等。

这篇文章我想讨论的是如何在C++模板中引用传入类的一个特定的成员变量。这个特性在我们设计新型类库的时候,很是有用。我今后想讲解的无内存管理的数据容器就与这个特性相关。

比如,如果我们想设计一个通用的Hash容器,我们肯定需要提供一个选择,让用户提供它们自己的Hash函数,同时,我们也需要提供一个默认的Hash函数,因为很多时候,我们只需要使用最简单的Hash函数,比如对于整数,我们取模(“%”)。这样如下的设计浮出水面:

template<classKeyType, class ObjType, ulong32 BucketNum, class HashFcn>

classHashContainer{

};

按照前面所述,我们需要提供一个默认的Hash函数,而这个函数,我们想让它以模板参数的形式传入,所以我们肯定需要实现一个仿函数:

ClassIntergerHasher{

Public:

Ulong32 operator()(KeyType key){

Return ulong32(key%BucketNum);

}

};

好的,问题好像来了。假如现在我们有两个类,它们想使用这个容器。这两个类的定义如下:

Class A{

Private:

Ulong32               fsid;  //hash键值

};

Class B{

Private:

Ulong32               volid; //hash键值

};

它们都只需要默认的hash函数就行,那么我们的Hash模板如何知道它们使用哪个域来作为hash的键值呢?

这时,我想到了函数成员指针。也许我们可以利用它。所以定义了如下的模板构造函数:

template<classKeyType, class ObjType, ulong32 BucketNum, class HashFcn>

classHashContainer{

public:

HashContainer(KeyType ObjType::*key):mKey(key), mHasher(IntergerHasher<KeyType, BucketNum>())

{}

Void       add(ObjType     *p);

Private:

ObjType*            ObjType::*mKey;

HashFcn               mHasher;

};

这里视乎还有个问题,如何使用这个成员指针呢?我们以memberfunction add()为例:

template<classKeyType, class ObjType, ulong32 BucketNum, class HashFcn>

voidHashContainer<KeyType, ObjType, BucketNum, HashFcn >::add(ObjType *p)

{

ulong32     bucket = mHasher(p->*mKey);

…..

}

我们的模板有了这个技能,就可以如此的使用这个Hash容器了:

.hxx

Class A{

Private:

Ulong32               fsid;  //hash键值

Static HashContainer<ulong32,A, 1543, IntegerHasher<ulong32, 1543>) manager;

};

Class B{

Private:

Ulong32               volid; //hash键值

Static HasherContainer<ulong32,B, 1543, IntegerHasher<ulong32, 1543>) manager;

};

.cxx

HashContainer<ulong32,A, 1543, IntegerHasher<ulong32, 1543> A::manager(&A::fsid);

HashContainer<ulong32,A, 1543, IntegerHasher<ulong32, 1543> A::manager(&B::volid);

也许你们会问,我们在HashContainer中可以使用A或B的私有变量吗?可以吗?你试试!!!

如何在模板中引用参数类中的一个特定member的更多相关文章

  1. 转载:C++中两个类中互相包含对方对象的指针问题

    原文链接:http://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某 ...

  2. 【记录】mybatis中获取常量类中数据

    部分转载,已注明来源: 1.mybatis中获取常量类中数据 <update id="refuseDebt"> UPDATE dt_debt a SET         ...

  3. 实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法

    实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法 #import <Found ...

  4. 尚硅谷面试第一季-11MyBatis中当实体类中的属性名和表中的字段名不一样怎么办

    问题: MyBatis中当实体类中的属性名和表中的字段名不一样 ,怎么办 ? 解决方案: 1.写sql语句时起别名 <!-- id属性:必须是接口中方法的方法名 resultType属性:必须是 ...

  5. cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法

    //*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...

  6. thymeleaf模板引擎调用java类中的方法(附源码)

    前言 <Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦> 由于开源了项目的缘故,很多使用了My Blog项目的朋友遇到问题也都会联系我去解决 ...

  7. 关于类中的参数类型和return返回值

    基础有些忘了,现在重新巩固一下 先定义一个Person类 class Person(): def __init__(self,name,age,height): self.name=name, sel ...

  8. C#中引用参数ref和输出参数out

    引用参数 用于按引用传递自变量. 为引用参数传递的自变量必须是具有明确值的变量,并且在方法执行期间,引用参数指明的存储位置与自变量相同. 引用参数使用 ref 修饰符进行声明. 输出参数 用于按引用传 ...

  9. Python中从B类中调用A类的方法。

    好久没上了,Python还在学--最近进度有点慢... 下面代码记录了一个不太好理解的点,自己写了个小例子,总算是理顺了. B类想要调用A类,自己在网上看了一下其他人的回复:创建A类的实例,直接调用这 ...

随机推荐

  1. NetCore控制台实现自定义CommandLine功能

    命令行科普: 例如输入: trans 123 456 789 -r 123 -r 789上面例子中:trans是Command,123 456 789是CommandArgument,-r之后的都是C ...

  2. 一列道出yield和生成器的真谛

    均匀大小的块 def chunks(l, n): """Yield successive n-sized chunks from l.""" ...

  3. MySql 模糊查询、范围查询

    实例: SQL模糊查询,使用like比较关键字,加上SQL里的通配符,请参考以下: 1.LIKE'Mc%' 将搜索以字母 Mc 开头的所有字符串(如 McBadden). 2.LIKE'%inger' ...

  4. 【转】高效率编辑器VIM

    最近实习的时候需要在服务器上做Debug,不得不用到vim的相关操作.以前对vim这种被码农无数赞扬的神器望而却步,但今天试了之后感觉还是不错的.以后争取少用鼠标,少用insert模式. 这是从网上看 ...

  5. rest framework 类 继承图

  6. Qt Quick快速入门之线程基础

    首先必须明确的是,Qt中的线程使用是相对复杂的,并不像C#中那么随意,特别是结合串口.网络编程等,使用时稍有不慎就会出问题,然后Qt里面经常出了问题就直接崩溃(这个真是谁用谁知道),所以如果在功能上用 ...

  7. 【Naive Splay Template】

    写小作业的时候重新复习了一下splay 只支持插入,删除,查k大,查节点数.没有迭代器. T类型需要重载==和<,要调用拷贝构造函数. template<class T> class ...

  8. 课堂练习—hash

    课堂练习-hash 要求: 利用除留余数法为下列关键字集合的存储设计hash函数,并画出分别用开放寻址法和拉链法解决冲突得到的空间存储状态(散列因子取0.75) 关键字集合:85,75,57,60,6 ...

  9. [CodeForces-585F]Digits of Number Pi

    题目大意: 给你一个数字串s,一个序列范围l和r,(l和r的数字位数为d)求l到r中有多少个数,满足它的长度为d/2的子串,能够在s中被匹配. 思路: 首先将s中每一个长度为d/2的子串插入后缀自动机 ...

  10. hdu 4540 dp

    题意: 假设: 1.每一个时刻我们只能打一只地鼠,并且打完以后该时刻出现的所有地鼠都会立刻消失: 2.老鼠出现的位置在一条直线上,如果上一个时刻我们在x1位置打地鼠,下一个时刻我们在x2位置打地鼠,那 ...