c++模版的一些使用方法(一)

在一个项目中,我认为c++模版的主要应用是对一些基础组件的封装。因为基础组件往往是供上层开发人员使用的,并且它一般具有不确定性和支持的旷阔性,stl的容器是个很好的例子。容器支持n中类型,这表现了它的广阔性,它又可以通过顺序和链式实现,这表现了不确定性。我把这些“重量级”的应用认为是模版的主要应用。

此外,有使用技巧的人也会通过使用模版来“耍一些小聪明”,这指的是通过模版简单化很多工作。

这里记一下我认为模版比较有用的基础特性:

1.带默认类型或默认参数的模版

example:

template<class T, int size=100>//将size的默认值设为100
class MyArr
{
    T arr[size];
};

MyArr<int, 10> arr;
MyArr<int> arr1;//实例化模版时如果没有指定size,将使用默认值

或者模版也可以是带默认类型

example:

template<class T = int>//默认类型是int
class MyArr
{
    T* p;
};

MyArr<float> da;//实例化出float类型
MyArr<int> di;//实例化出int类型
MyArr<> dd;//不指定类型,使用默认的int类型,效果和上面一行相同

2.模版的特化和偏特化

模版用于泛型,它指的是提供一个通用的框框,这个框框可以支持各种各样的类型,但重要的是这些各种各样的类型在模版内部所走的流程是一致的,但是可能会在使用中有这样的需求:

        我希望在这各种各样的类型中,某几种类型的处理方式区别于其他大多数类型。

这就需要使用模版的特化或偏特化,任何一组特化或偏特化都是该模版所有可能实例化出的类型的一个子集。

example:

//模版的全集定义
template<class T,class P>
class AClass
{
public:
    int x;
    void print()
    {
        printf("%d\n",x);
    }
};

//某一个子集:第二个类型为double,一种偏特化
template<class T>
class AClass<T,double>
{
public:
    int x;
    void print()
    {
        printf("specialize for double ---%d\n",x);
    }
};

//某一个子集:第一个类型为float,第二个类型为double,一种特化
template<>
class AClass<float,double>
{
public:
    int x;
    void print()
    {
        printf("specialize for float & double ---%d\n",x);
    }
};

AClass<int,char> a;
a.print();
AClass<int,double> b ;//使用偏特化来实例化
b.print();
AClass<float,double> c;//使用特化来实例化
c.print();
AClass<double,double> d;//注意这里,这里使用偏特化来实例化,而不是使用全集定义来实例
d.print();
output:



模版特化和偏特化的应用:

应用一:建立类似防火墙的黑名单\白名单机制

                意思就是对于一个泛型,建立类型过滤,只允许一部分类型使用该模版

                下面的例子将允许int和char类型实例化该模版

//模版全集
template<class T>
class WhiteList
{
public:
    void print()
    {
        printf("123\n");
    }
};

//特化int
template<>
class WhiteList<int>;//不实现

//特化char
template<>
class WhiteList<char>;//不实现


int _tmain(int argc, _TCHAR* argv[])
{
    WhiteList<bool> b;
    b.print();
    WhiteList<char> c;//编译通不过
    c.print();
    WhiteList<int> i;//编译通不过
    i.print();
    WhiteList<double> d;
    d.print();
	return 0;
}

应用二:修改第三方库的代码

               假设现在有这样一种需求A,可以通过使用某开源库B中的某个模块C实现,模块C在文件C.h中定义并实现,它是一个模版类型的类d,我们只需要include<c.h>就可以在自己的代码中使用类d定义对象了。但是使用的过程中发现,C中有部分代码和我们的需求有小小的偏差,那么该怎么办。可能最直接的办法是修改c.h,但是问题是,c.h并不是我们自己的代码,直接修改第三方库,有可能会对其他项目的使用造成影响。那么怎么办呢?

                如果注意到类d是模版类型的,那么就有办法了。既然是模版类型,那么我们就可以在自己的代码中特化这个模版类,特化出我们需要的那个子集,这样,我们就必须在自己的代码中重新写一遍这个特化的模版,然后我们就可以在这里做一些小小的修改。

下面的例子中,第三方开源库B的c.h文件的模版类d中的print函数中,会在最后输出一个回车换行,但是我们实际使用时并不想有这个回车换行。那么就可以通过特化该模版来干掉这个回车换行。

使用模版特化修改前:

//-------第三方开源库B中的c.h
template<class T,class P>
class aClass
{
    //.........
public:
    void print()
    {
        printf("123456\n");
        printf("\n");//这里有一个回车换行
    }
};

//-------自己的代码
int _tmain(int argc, _TCHAR* argv[])
{
    aClass<int,bool> a;
    a.print();
    return 0;
}


使用模版特化修改代码,去掉最后的回车换行:

//-------第三方开源库B中的c.h
template<class T,class P>
class aClass
{
    //.........
public:
    void print()
    {
        printf("123456\n");
        printf("\n");
    }
};

//-------自己的代码
template<>
class aClass<int,bool>//特化为我们需要的子集
{
    //....其他的都不修改
public:
    void print()
    {
        //只修改这里
        printf("123456\n");
        //printf("\n");去掉
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    aClass<int,bool> a;
    a.print();
	return 0;


其实就是编译器以最强匹配原则来找该模版实例化后的类型定义,他认为

template<>

class aClass<int,bool>

template<class T,class P>

class aClass

的匹配度高,所以就用前者了

需要注意的是,当你在另一个文件中做特化时(在使用开源库时,一定是include了别人的头文件,然后在自己的文件中特化),编译连接时就会在多个obj(起码是两个吧...)中出现该模版类的定义,这时会出现link错误,这是很正常的,只需要把特化的类声明成inline即可。(上面例子我省事直接把模版的全集定义也写在当前文件中了,所以特化那就不用inline了)


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
主栏目导航:首页、商品列表、特价商品、拍卖、团购、品牌专卖 次栏目导航:注册、登陆、留言, 我的圈子,缺货登记,帮助 头部栏目导航: 城市切换 我的帐户 点卡 拍卖 商铺 点评空间 购物资讯 社区 底部导航:首页 | 店铺介绍 | 联系我们 | 留言中心 | 我要开店 搜索 :商品搜索,高级搜索 定单搜索 一、头部栏目导航 我的帐户 将进入我的会员中心如没登陆将转到登陆界面 点卡 展现本网站推荐优惠点卡,以及对点卡的购买 拍卖 展现本网站最新拍卖商品及会员对所感兴趣的商品价格竞拍. 商铺 展现网站中的全部商铺可以按时间或人气排序 选择一个商铺后将进入店铺页面(铺子功能主要有) 商铺首页(显示该店铺的详细信息,及本店铺的信誉度和推荐物品.可根据商品名称收索该铺子此商品) 商品列表(显示本店铺所卖的商品) 拍卖(本店铺拍卖商品) 团购(本店团购商品) 店铺介绍 留言中心(会员对此店铺的意见及评价信息) 点评空间 点击进去点评专区 点评排行 (根据点击率进行排序评论) 热门点评 (根据回复最多的评论进行排序) 热门标签 最新点评 最多鲜花(根据所得花数进行排序,点击此评论可进行送花,支持,反对意见) 购物资讯 社区 二、主栏目导行: 首页 商品列表 展现出商品分总类和总类下的所有商品分类,及商品销售排行榜 特价商品 主要展现特价打折商品,方便会员查看购买. 团够商品 品牌专卖 展现某品牌下对应的所有该品牌物品,更利于对商品分类的查询 三、次栏目导航 登陆 会员登陆 免费注册 免费注册会员,将可以在本站购买商品及获取对应的积分和商品优惠折扣. 购物车 查看在本站所购买的所有商品和所需总价格. 留言 查看对本网站的所留意见,建议. 我的圈子 点击我的圈子将进入圈子主页 对圈子的搜索 (根据圈子名称查询对应圈子) 圈子排行 (根据圈子加入会员数进行排行) 热门圈子 (根据发贴数量进行排序) 热门标签 圈子热贴(圈子中回复帖子最多的来排序) 推荐圈子 圈子添加 选中圈子进入该圈子的详细信息页和该圈子下发表的所有帖子 缺货登记 会员在本网站查询不到所需商品可以在此登记 四、搜索 商品搜索 根据商品名称进行查询 高级搜索 根据关键字 名称 ,类别 商品编码 价格范围及说明进行关联查询 订单查询 根据定单号查询此订单详细信息 易想商城会员中心 一级栏目:我是买家 我是卖家 基本信息:会员头像,会员名字,会员等级,积分,我的圈子、店铺, 退出 交易管理、帐户管理、点评圈子、个人信息 一、 交易管理 我的购物车:显示还在购物车中的商品 订单中心:所有订单、需要支付的订单、处理中的订单、需要确认收货的订单、历史订单【仿当当的】 交易明细: 统计记录该会员的所有支出,收入交易记录 我的拍卖: 记录该会员在本网站拍卖的所有商品 我的团购: 该会员所参加团购物品. 二、 帐户管理 账户信息:记录本会员全部详细信息,及兑换点券. 兑换有效期,在线支付,修改信息,我的短消息等功能. 会员积分:统计该会员在本网站的积分,及积分详细记录. 收货地址管理: 查看和添加收货人的详细地址 充值卡充值:模仿动易功能,进行会员冲值. 暂存架: 所关注的所有物品存放处.方便过后购买及关注 收藏夹: 该会员喜欢商品收藏处方便关注浏览 三、 点评圈子 我的点评: 包括我的点评和我点标签, 我的点评主要包括会员所发表的所有评论及其他会员对所发表评论的支持反对查看. 我的圈子:包括发起的圈子和参与的圈子及相对圈子所发表帖子管理. 好友管理:包括好友管理、添加好友、创建新组、分组管理 站内短信:反馈留言、撰写短消息、草稿箱、收件箱、发件箱、废件箱 四、 个人信息 个人资料: 记录该会员所有详细信息 修改密码: 会员登陆密码修改 修改资料: 修改会员的基本信息 五、 功能说明之会员积分 功能说明: (1)获得积分: A、商品积分:是购买商城上赠送积分的商品,交易成功后就可以获得相应的积分。 B、注册积分:积分可以在后台设置多少,当注册并通过认证时可获得该积分; C、介绍奖励:介绍别人注册成为商城的注册会员,可以获得积分,积分数量可以后台设置。 D、购买积分:将商城的余额转换为积分。人民币与积分的对换比例后台设置 E、会员评价:会员评价积分,积分规则后台设定; (2)积分扣除:商城用户可使用积分来兑换商品,但用户所购买的含有积分的商品退货,商城系统会在用户自己的“积分管理”中扣除相应的积分,若用户的积分不足,则相应的在商品的退款金额中减去相应的金额,按照不足积分数

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值