C++之将与参数无关的代码抽离templates(44)---《Effective C++》
来源:互联网 发布:iphone se 知乎 编辑:程序博客网 时间:2024/05/22 08:12
条款44:将与参数无关的代码抽离templates
template <typename T,std::size_t n>class SquareMatrix{public: ... void invert();};
现在,考虑这些代码:
SquareMatrix<double,5) sm1;...sm1.invert();SquareMatrix<double,10> sm2;...sm2.invert();
这样将会生成两份invert,这些函数并非完全相同,因为其中一个操作的是5*5矩阵而另一个是10*10的矩阵,但除了常量5和10,两个函数的其他部分完全相同,这是tempalte引出代码膨胀的一个典型例子。
可以发现这两个函数完全相同,只除了一个使用5而另一个使用10,那你会怎么做?以5和10来调用这个带参数的函数,而不重复代码。下面我们来进行第一次对SquareMatrix的修改:
策略1:
template <typename T>class SquareMatrixBase{protected: ... void invert(std::size_t matrixSize); ...};template <typename T,std::size_t n>class SquareMatrix:private SquareMatrixBase<T>{private: using SquareMatrixBase<T>::invert;public: ... void invert(){this->invert(n);}};
带参数的invert位于base class SquareMatrixBase中,和SquareMatrix一样,SquareMatrixBase也是个template,不同的是它只对“矩阵元素对象的类型”参数化,不对矩阵的尺寸参数化,因此对于某给定之元素对象那个类型,所有矩阵共享同一个(也是唯一一个)SquareMatrixbase class,它们也将因此共享这唯一一个class内的invert。注意这些函数中我们使用“this->”标记,因为如果不这样做,便如上篇博客中所讲的那样,模板化基类内的函数名称会被derived class掩盖,同时我们这儿使用private继承的原因是base class SquareMatrixBase只是为了帮助derived class SquareMatrix是实现,子类和父类之间不是“is-a”关系。
策略2:
针对SquareMatrixBase::invert的实现,我们该如何操作呢?解决办法是让SquareMatrixBase贮存一个指针,指向矩阵数值所在的内存,而只要它存储了这些东西,也就可能存储矩阵尺寸,如下:
template <typename T>class SquareMatrixBase{protected: SquareMatrixBase(std::size_t n,T* pMem):size(n),pDate(pMem){ } void setDataPtr(T* ptr){pData=ptr;} ...private: std::size_t size; T* pData;};
这允许derived class中决定内存分配方式,这里我们针对derived class有两种分配方式:
1)存储指针数组,这样可能导致对象吱声超级大!!!
template <typename T,std::size_t n>class SquareMatrix:private SquareMatrixBase<T>{public: SquareMatrix():SquareMtrixBase<T>(n,data){} ...private: T data[n*n];};
2)把每一个矩阵的数据放进heap中,即通过new进行动态内存分配;
template <typename T,std::size_t n>class SquareMatrix:private SquareMatrixBase<T>{public: SquareMatrix():SquareMatrixBase<T>(n,0),pData(new T[n*n]){ this->setDataPtr(pData.get()); } ...private: boost::scoped_array<T> pData;};
PS:
1)non-type template parameters(非类型模板参数):模板参数并不局限于类型,template <<>typename T,int n>或者template <<>typename T,size_t n>等等,第二个就是非类型模板参数!
2)type parameters:标准的类型模板参数,template <<>typename T>。
总结:
1)template生成多个classes和多个函数,所以任何template代码都不应该与某个造成膨胀的template参数产生相依关系;
2)因类型模板参数(non-type template parameters)造成的代码膨胀,往往可以消除,做法是以函数参数或者class成员变量代替template参数;
3)因类型参数(type parameters)而造成的代码膨胀,往往可以降低,做法是让带有完全相同的二进制表搜狐的具现类型共享实现码。
- C++之将与参数无关的代码抽离templates(44)---《Effective C++》
- 《Effective C++》读书笔记之item44:将与参数无关的代码抽离templates
- Effective C++ Item 44 将与参数无关的代码抽离 templates
- Effective C++ 44条 将与参数无关的代码抽离templates
- Effective C++:条款44:将与参数无关的代码抽离template
- 读书笔记《Effective C++》条款44:将与参数无关的代码抽离template
- 条款44:将与参数无关的代码抽离templates
- 条款44:将与参数无关的代码抽离templates
- C++ - 将参数无关的代码抽离模板(templates)
- Effective C++学习_条款44:将与参数无关的代码抽离
- [翻译] Effective C++, 3rd Edition, Item 44: 从 templates(模板)中分离出 parameter-independent(参数无关)的代码(上)
- [翻译] Effective C++, 3rd Edition, Item 44: 从 templates(模板)中分离出 parameter-independent(参数无关)的代码(下)
- 条款44:将与参数无关的代码抽离template
- (Effective C++)第七章 模板与泛型编程 (Templates and Generic Programming)
- 与C语言“无关”的C语言
- 与C语言“无关”的C语言
- Item 44 与模板参数无关的代码
- 条款45:将与函数无关的代码抽离template
- linux下的定时或计时操作(gettimeofday等的用法,秒,微妙,纳秒
- odoo 定时任务的使用方法
- 视频目标检测--Flow-Guided Feature Aggregation for Video Object Detection
- 【云计算的1024种玩法】自己搭游戏服务器:我的世界Minecraft
- WPF实现窗体最小化后小图标在右边任务栏下
- C++之将与参数无关的代码抽离templates(44)---《Effective C++》
- react native 震动 Vibration 使用详解
- DSP28335官方例程Control Suit(1)——LED实验
- java基础复习--复习总结11
- C++位运算
- Idea for Mac 快捷键
- css学习笔记之水平居中
- HDU6069 Counting Divisors 区间素数筛法
- Java基础一:关键字、标示符、变量、常量和数据类型转换