Effective C++ 条款44

时间:2022-03-29 11:49:05

本节条款的标题是:将与參数无关的代码抽离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&plus;&plus; -----条款44:将与参数无关的代码抽离templates

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

  2. &lbrack;More Effective C&plus;&plus;&rsqb;条款22有关返回值优化的验证结果

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

  3. More Effective C&plus;&plus; 条款0,1

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

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

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

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

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

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

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

  7. Effective C&plus;&plus; -----条款19:设计class犹如设计type

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

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

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

  9. Effective C&plus;&plus;&colon;条款27——条款

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

随机推荐

  1. java jdbc 封装。。

    JDBC工具类...package it.cast.jdbcutils; import java.io.InputStream; import java.sql.Connection; import ...

  2. 【POJ】【1821】Fence

    DP/单调队列优化 题意:k个人粉刷总长为n的墙壁(或者说栅栏?),每个人有一个必刷点s[i](这个人也可以一点也不刷,如果刷就必须刷这个点),最大粉刷长度l[i](必须是连续粉刷一段),和粉刷一格的 ...

  3. KVC 和KVO浅谈

    一.KVC:Key-Value -Coding :直译为:键-值-代码:即:对键值进行改变的代码方法   该方法是OC(Object-C)为我们提供的一个不通过初始化方法而直接改变对象实例变量值的一种 ...

  4. css标准导航代码

    <!-- 例子解析: --> --> <!-- list-style-type:none - 移除列表前小标志.一个导航栏并不需要列表标记 --> <!-- 移除浏 ...

  5. android sdk manager无法更新

    问题描述:       Android SDK Manager 无法下载更新,或者更新速度超慢,或者待安装包列表不显示.   解决方法:     第一,我们先修改下hosts文件.该文件的位置在系统盘 ...

  6. &lbrack;转载&rsqb; http长连接和短连接

    转载自http://blog.csdn.net/shine0181/article/details/7799754/ HTTP实现长连接 HTTP是无状态的 也就是说,浏览器和服务器每进行一次HTTP ...

  7. 微信小程序自动化测试--接口测试

    偷得一篇文章: postman测试微信小程序接口---postman https://www.sunzhongwei.com/using-the-postman-test-wechat-mini-ap ...

  8. 数据分析与科学计算可视化-----用于科学计算的numpy库与可视化工具matplotlib

    一.numpy库与matplotlib库的基本介绍 1.安装 (1)通过pip安装: >> pip install matplotlib 安装完成 安装matplotlib的方式和nump ...

  9. webapi使用swagger出现&OpenCurlyDoubleQuote;Cannot read property &&num;39&semi;parameters&&num;39&semi; of null”

    前端时间在webapi项目使用swagger来提供接口文档及测试工具,按网上方法(http://wmpratt.com/swagger-and-asp-net-web-api-part-1)配置好之后 ...

  10. NoHttp封装--07 自定义异步任务框架

    MainActivity: public class MainActivity extends Activity implements View.OnClickListener { .... @Ove ...