摘要:
1、所谓虚化,就是根据引用或者指针的真实类型,决定调用哪个方法。2、构造方法虚化,就是根据引用(或者指针)的真实类型,构造出一个对象,如果指针的真实类型是Base,返回Base*;如果指针的真实类型是Derived,返回Derived*。解决办法是:Base定义一个virtual方法Clone,调用new Base(*this),返回Base*;Derived重写Clone方法,调用new Derived(*this),返回Derived*。注意:一般情况下,子类重写父类方法,要求返回类型必须一致。目前,父类返回Base*,子类重写可以返回Derived*,也就是说C++支持协变。(口诀:进去 阅读全文
摘要:
1、程序库的设计是一种权衡的结果。体积小,速度快往往不能移植。可移植,通用的程序库往往意味着冗余和效率低下。2、因此,选择程序库的时候,需要进行取舍。比如:iostream和stdio。iostream具有类型安全性,可扩充,而stdio的效率更高。注意,对性能评估的时候,不要猜,应该进行多次实验进行确认。 阅读全文
摘要:
1、基本思想就是:如果将来肯定要做某件事,并且这件事情耗时,提前把东西准备好,先做一部分。常用的使用场景有:2、考虑一个大的数据集合,集合中元素不断变化。经常要取出里面的最大值,正常的做法是:每次调用的时候,计算出最大值,这可能是一个耗时的操作。既然是经常取出最大值,那我就实时(每次对集合增删改的时候)更新最大值,需要的时候直接就返回最大值了。3、考虑stl中的vector,vector有5个元素,假设vector的内存刚好容纳5个元素,现在增加一个元素。那就意味着必须分配一块6个元素的内存,把原来的5个元素和新增的1个元素copy过来。这显然效率很低。解决办法是:预留一些内存。4、较快的速度 阅读全文
摘要:
1、缓式评估其实就是拖延战术,直到逼不得已的时候才去计算。缓式评估的使用场景有:2、引用计数,考虑String,String是一个内含char指针(char指针以'\0'结束)的资源管理类,正常情况下,String的copy构造和copy赋值都是深层copy,也就是对char指针指向的内容做一个副本,这个效率显然很低。考虑String s2 = s1; 后面的代码可能只是读取s2,没有必要做深层copy,s2与s1可以共享一份数据,也就是使用引用计数,来实现String。但是,当修改String的时候,必须做一个深层copy,也就是拖延战术。3、区分读与写,考虑cout< 阅读全文
摘要:
1、考虑二维数组,在C++中,以先行后列的方式存储连续的数组元素。也就是同一行的元素在一起,同一列的元素之间有间隔,且间隔相同。理想情况下,二维数组的元素是随机访问的,可以直接定位,即i*列数+j。因此,对于二层for循环访问二维数组的元素,先行后列与先列后行的效率应该是一样的。但是,二维数组的数据往往需要多个内存分页才能容纳,由于C++同一行的元素在一起,先行后列,更符合空间局部性,可以减少换页。因此,先行后列的效率高。2、考虑二层for循环,有大循环和小循环。大循环在内部效率高。为什么?可简单地认为,跨越循环层是个耗时耗资源的操作,大循环在内部,跨越循环层的次数少。从另一方面理解,大循环在 阅读全文