在使用templates时可能会造成代码膨胀,所以要找出相同的部分,但在templates中重复是隐晦的,书上的例子
template<typename T,std::size_t n>//template支持n*n矩阵,元素是的类型为T
class SquqreMatrix
{
public:
void invert();//求逆矩阵
}
考虑如下调用
SquareMatrix<double 5> sm1;
sm1.invert();
SquareMatrix<double 10> sm2;
sm2.invert();
上述调用会具现化两份invert,因为矩阵的阶数不同,然而两份invert除了n不同其他操作都是一样的,就造成了冗余。解决方式是为invert建立一个带参数的函数
template<typename T>
class SquareMatrixBase
{
protected:
SquarematrixBase(std::size_t n,T* pMem):size(n),pData(pMem){}
void setDataPtr(T* ptr){pData=ptr;}
void invert(std::size_t matrixSize);
private:
std::size_t size;//矩阵的大小
T* pData;//指针,指向矩阵的内容
}
template<typenmae T,std::size_t n>
class SquareMatrix:private SquareMatrixBase
{
private:
using SquareMatrixBase<T>::invert;
public:
SquareMatrix():SquareMatrixBase<T>(n,data){}
void invert()
{
this->invert(n);
}
private:
T data[n*n];
}
相同类型的派生类共享同一个父类SquareMatrixBase,父类是与位数无关的模板类, 派生类SquareMatrix没有大变化,只是在invert的时候,调用父类的invert函数,并把矩阵维数n传过去。
在调用的时候针对相同类型维数不同的矩阵,invert中生成的冗余代码非常少,只有一句调用父类invert函数的代码,父类的invert与模板参数无关,只生成一份。从这个角度来看,将与参数无关的代码抽离template起到了减少代码冗余度的优化作用。
请记住:
1.Templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系
2.因非类型模板参数而造成的代码膨胀,往往可以消除,做法是以函数参数或class变量代替template参数
3.因类型参数而造成的代码膨胀,往往可降低,做法是让带有完全相同二进制表述的具现类型共享实现码