本节条款的标题是:将与參数无关的代码抽离templates

学习本节条款首先须要明确一件事情,那就是模板实例化的过程会不会反复?

我们来举个样例:

#include<iostream>
using namespace std; template <typename T>
T Try(T m)
{
return m;
} int main()
{
Try(10);
Try(1);
}

我们看以上简单的代码。每一个人都知道模板被调用了两次,是的,这显而易见。但是模板也被实例化了两次吗?其实,模板仅仅实例化了一次。

我们再举个样例:

#include<iostream>
using namespace std; template <typename T>
T Try(T m)
{
return m;
} int main()
{
Try(10);
Try(1.01);//注意!此时是一个double型
}

这个时候每一个人都知道模板被调用了两次。模板也被实例化了两次吗?其实,模板确实实例化了两次。

比較以上两个样例。大家明确了什么?那就是,模板函数的实例化次数和调用次数没有直接关系,而是和调用类型的种类有关。同种类型假设已经调用,模板函数会反复利用上次的实例化样例。而不会又一次分配内存实例化。假设,大家明确这一点本节条款就能理解了。

我们利用template就是为了让代码编写更简短。利用内存更小。但是,普通情况下非常多程序猿仅仅能做到第一步,而不能充分在内存中发挥代码的复用性。

例如以下书上样例:

template<typename T, std::size_t n>//T为数据类型,n为矩阵大小
class SquareMatrix{
public:
……
void invert();//求逆运算
};
SquareMatrix<double,5> sm1;
sm1.invert();//调用SquareMatrix<double,5>::invert
SquareMatrix<double,10> sm2;
sm2.invert();//调用SquareMatrix<double,10>::invert

上面的代码会在运行的过程中,详细化两份invert()函数。这两份函数差点儿全然同样,所以对于内存来说是种浪费。假设想要弥补这样的缺点,我们能够用下面对照样例:

template<typename T>
class SquareMatrixBase
{
public:
SquareMatrixBase(T* p) : DataPointer(p){}
void Invert(size_t n){}
private:
T* DataPointer;
}; template <typename T, size_t n>
class SquareMatrix: private SquareMatrixBase<T>
{
public:
SquareMatrix() : SquareMatrixBase(Data)
{}
void Invert()
{
SquareMatrixBase::Invert(n);
}
private:
T Data[n * n];
}; SquareMatrix<double,5> sm1;
sm1.invert();
SquareMatrix<double,10> sm2;
sm2.invert();

当我们再次调用以上语句时,SquareMatrixBase类的实例在内存中仅仅生成一次。由于每次调用都是double 型的SquareMatrixBase。

然后矩阵数据是用指针訪问,同一种数据不会被拷贝多份,这样也降低了内存利用。

总之。下面三条非常重要:

1. Template生成多个classes与多个函数。所以不论什么template代码都不该与某个造成膨胀的template參数产生相依关系。

2. 因非类型模板參数而造成的代码膨胀,往往能够消除,做法是以函数參数或者class成员变量替换template參数。

3. 因类型而造成的代码膨胀,也能够降低,做法是让带有全然同样二进制表述的具现类型共享实现码。

Effective C++ 条款44的更多相关文章

  1. Effective C++ -----条款44:将与参数无关的代码抽离templates

    Templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系. 因非类型模板参数(non-type template para ...

  2. [More Effective C++]条款22有关返回值优化的验证结果

    (这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...

  3. More Effective C++ 条款0,1

    More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...

  4. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

  5. Effective C++ -----条款28:避免返回handles指向对象内部成分

    避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...

  6. Effective C++ -----条款21:必须返回对象时,别妄想返回其reference

    绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...

  7. Effective C++ -----条款19:设计class犹如设计type

    Class的设计就是type的设计.在定义一个新type之前,请确定你已经考虑过本条款覆盖的所有讨论主题. 新type的对象应该如何被创建和销毁? 对象的初始化和对象的赋值该有什么样的区别? 新typ ...

  8. Effective C++ -----条款18:让接口容易被正确使用,不易被误用

    好的接口很容易被正确使用,不容易被误用.你应该在你IDE所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...

  9. Effective C++:条款27——条款

    条款27:尽量少做转型动作 单一对象可能拥有一个以上的地址!

随机推荐

  1. jQuery简单过滤选择器

    <html xmlns="http://www.w3.org/1999/xhtml"> <head>     <!--jQuery选择器详解 根据所获 ...

  2. Help Johnny-(类似杭电acm3568题)

    Help Johnny(类似杭电3568题) Description Poor Johnny is so busy this term. His tutor threw lots of hard pr ...

  3. 那些年踩过的坑之:first-child伪类选择器

    原文:那些年踩过的坑之:first-child伪类选择器 :first-child 选择器用于选取属于其父元素的首个子元素的指定选择器.——w3school 嗯,乍一看好像说的不是很明白,因此这个选择 ...

  4. android 项目中使用对话框统一封装

    近期在做拼车项目中使用到了一些对话框,而且在非常多地方都使用到了,既然非常多地方使用到,那么肯定要封装一下,

  5. 【网络协议】TCP交互数据流和数据流成块

    前言 建立在TCP协议上的应用层协议有非常多,如FTP.HTTP.Telnet等,这些协议依据数据传输的多少能够分为两类:交互数据类型和成块数据类型. 交互数据类型,如:Telnet,这类协议一般仅仅 ...

  6. OSPF理论总结

    OSPF学习总结一.OSPF协议的报文类型: 1. Hello 报文:主要用来发现.建立和维护邻居关系. 2. DD报文:数据库的描述报文,主要用来两台路由器的数据库同步. 3. LSR报文:链路状态 ...

  7. 安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题(Final Result: Installation failed with error code: (0x80070643), "安装时发生严重错误 " (Ela)

    原文:安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题(Final Result: Installation failed with error code: (0x800706 ...

  8. CF 553A 组合DP

    http://codeforces.com/problemset/problem/553/A A. Kyoya and Colored Balls time limit per test 2 seco ...

  9. 配置JVM内存 查看内存工具

    一.配置JVM内存 1.配置JVM内存的參数有四个: -XmxJavaHeap最大值.默认值为物理内存的1/4.最佳设值应该视物理内存大小及计算机内其它内存开销而定. -XmsJavaHeap初始值, ...

  10. 理解cookie的path和domain属性(转)

    今天在做验证码时发现一个问题:A.B窗口都打开同一个页面,A先生成一个验证码,B再生成验证码,这时A所生成的验证码被B覆盖掉了.原因是使用了同名的cookie来存储验证码.一时找不到解决方法就参考了W ...