大整数类的实现(3)(原创)

 本来现在我应该要介绍HugeNumberBase的实现了,但是我不准备在这里介绍。

因为HugeNumberBase的实现是需要详细解说的,可能要花上不久的时间和不少的篇幅,我觉得可能先等我把所有其他“外围”代码都解决完了,再来专心对付这个“核心”会比较好,所以我这里介绍DataAllocation.h和Helper.h的实现。

 

4.DataAllocation.h

——————————————————————————————————

/*
 * Copyright (c) 2005 by DoZerg.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 */
#pragma once

namespace DoZerg{
//class DataInStack
 template<long N,typename __DataType>
 class DataInStack
 {
 public:
  typedef __DataType * ptr;
  typedef const __DataType * const_ptr;
  operator ptr(){
   return data_;
  }
  operator const_ptr() const{
   return data_;
  }
 private:
  __DataType data_[N];
 };
//class DataInHeap
 template<long N,typename __DataType>
 class DataInHeap
 {
 public:
  typedef __DataType * ptr;
  typedef const __DataType * const_ptr;
  DataInHeap():data_(new __DataType[N]){
  }
  DataInHeap(const DataInHeap & v):data_(new __DataType[N]){
   FromSelf(v);
  }
  ~DataInHeap(){
   delete [] data_;
  }
  DataInHeap & operator =(const DataInHeap & v){
   FromSelf(v);
   return *this;
  }
  operator ptr(){
   return data_;
  }
  operator const_ptr() const{
   return data_;
  }
 private:
  ptr data_;
  void FromSelf(const DataInHeap & v){
   memcpy(data_,v.data_,N * sizeof(__DataType));
  }
 };
//class DataAutoSelect : with a allocation selection strategy(if N<100 then DataInStack,else DataInHeap)
 template<long N,typename __DataType>
 class DataAutoSelect
 {
 public:
  typedef __DataType * ptr;
  typedef const __DataType * const_ptr;
  operator ptr(){
   return data_;
  }
  operator const_ptr() const{
   return data_;
  }
 private:
  template<bool,class T1,class T2>struct IfType{ typedef T1 RType; };
  template<class T1,class T2>struct IfType<false,T1,T2>{ typedef T2 RType; };
  typedef typename IfType< (N<100),DataInStack<N,__DataType>,DataInHeap<N,__DataType> >::RType RType;
  RType data_;
 };
}//namespace DoZerg

——————————————————————————————————

这里有3个类模版,DataInStack,DataInHeap和DataAutoSelect。

1)DataInStack

这个类模版从栈空间里“申请”数据data_,其实就是这句:

__DataType data_[N];

如果大整数本来是在栈空间里生成的,那么data_自然也在栈空间里了;如果大整数在堆空间里生成,那么data_也会存在于堆空间。

它有2个模版参数:

long N,

typename __DataType

第一个N是数据数组data_的长度,第二个__DataType是数据的类型。

这里用__DataType来抽象内部的数据类型,那么一个128bits的整数,可以用2个long long来表示,也可以用4个long来表示,甚至用16个char来表示。

DataInStack需要提供的接口,或者说“合格”的Alloc应该提供的接口包括:

    默认构造函数

    拷贝构造函数

    拷贝赋值函数

  typedef __DataType * ptr;
  typedef const __DataType * const_ptr;
  operator ptr();

  operator const_ptr() const;

后面几个直接写成代码形式,希望能更清晰。

对于DataInStack,前3个接口使用编译器自动的生成就行了,所以实际上它只提供了后4个接口。

2)DataInHeap

它与DataInStack的本质区别就是只存储data_指针,数据空间是在构造的时候new出来的,所以它的数据永远在堆空间里。考虑到大整数可能占用比较大的内存,把数据空间移到堆里也许能减轻线程栈空间的压力。

由于DataInHeap只存储数据的指针,那么编译器生成的浅拷贝函数就不够用了,所以它实现了一个Alloc应该具有的全部接口。

3)DataAutoSelect

这个类模版是我展示小小“技巧”的一个东西,本来是不需要的。

它的主要作用就是根据数据数组长度N的大小,来选择采用DataInStack还是DataInHeap,这里我的界限是100。如果N<100,将采用DataInStack;否则采用DataInHeap。

它首先实现了作为Alloc接口必须的东西,即public下的所有东西,然后把内部数据的表示进行了“技术处理”(当然还利用了DataInStack和DataInHeap拷贝函数)。

注意到这二行:

template<bool,class T1,class T2>struct IfType{ typedef T1 RType; };

template<class T1,class T2>struct IfType<false,T1,T2>{ typedef T2 RType; };

定义了一个类模版IfType,接受3个模版参数,并把T1定义成RType;

下面对IfType进行了特化,在第一个模版参数为false的情况下,把T2定义成RType;那么前面定义R1为RType的情况只能是第一个模版参数为true了。

于是这样IfType就成了一个类型选择器,根据第一个模版参数进行T1或T2的类型选择。

所以接下来的这行:

typedef typename IfType< (N<100),DataInStack<N,__DataType>,DataInHeap<N,__DataType> >::RType RType;

也就不再“神秘”。

IfType<

    (N<100),

    DataInStack<N,__DataType>,

    DataInHeap<N,__DataType>

>

IfType的第一个模版参数是(N<100),由它决定,最终是DataInStack<N,__DataType>定义成RType,还是DataInHeap<N,__DataType>定义成RType。

然后把这个RType定义成DataAutoSelect的RType。

于是根据N值来选择DataInStack或DataInHeap的目的就达到了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值