本篇增加了一些Effective STL的知识,Effective C++篇如想深入了解,请查阅书籍
1、如何让一个类不支持拷贝
可以将这个类的拷贝构造函数和赋值运算符设置为私有的,并且不给予任何实现,或者让这个类继承一个父类,这个父类的构造函数和赋值运算符是私有的
声明私有的,这样编译器不会自动生成public的拷贝构造函数,也能组织外部调用这两个函数,为了防止友元函数的调用,则使用空实现来避免
2、share_ptr和auto_ptr两个常用智能指针的区别是什么
auto_ptr类型的指针,每次析构之后都会释放自己持有的内存,当被拷贝的时候,为了不引起多次释放,将原指针指向nullptr,新指针将单独持有这块空间
share_ptr类型的指针,使用的引用计数,在拷贝后,每个指针都同事指向原来的内存单元,并且没有任何指针指向该内存是,空间才会被释放
3、将成员变量声明为private,可以保证数据的一致性
4、用非成员函数和非友元函数替换成员函数
(1)面对对象守则要求,数据应该尽可能的被封装,成员函数带来的封装性,比非成员函数的要低,非成员函数可对成员变量产生有较大的包裹弹性,
数据被越少访问,封装性就越强,因此,针对这个概念,非成员函数不能增加访问成员变量的数量,好好理解这句话,因为数据通常被声明为private,只有成员函数和友元函数可以访问,所以非成员函数只能调用成员函数来达到功能目的,所以没有减低数据的封装程度
(2)使用命名空间,将非成员函数和类放在一起,C++的标准库的组织方式,就是这样,标准库并不是单一的,而是有很多文件组成在一起的,每个头文件声明std的一些功能,客户只对他们所用的一小部分形成编译依赖
5、定义变量,只在使用的时候在定义,越晚越好
6、尽量少做转型动作
const_cast<T>():通常用来将对象的常量性移除,也是唯一具有此能力的转型操作符
dynamic_cast<T>():安全向下转型,子类转换为父类指针,当父类转换为子类指针的时候,如果父类中没有虚函数,会编译不过,如果有虚函数的时候,如果父类指针指向子类,可以返回预期的地址,如果父类没有指向子类,会返回null,是安全的,但是耗费运行成本,依靠的是虚函数表,转换的时候,通过续表指针可以获取到该类的对象的所有虚函数,包括其父类的
reinterpret_cast<T>():不建议使用
static_cast<T>():强制隐式转型(子类的指针或引用转换成父类的指针或引用,父类的指针或引用转换成子类的指针或引用)
7、什么样的函数适合定义为内联函数。
内容简单,需要重复调用,但是不可以是递归函数,不能有循环体,switch语句,不能进行异常接口声明
优点:调试过程和二进制升级更容易,可以使潜在的代码膨胀问题最小化,程序的速度提升机会最大化,避免频繁调用函数堆栈内存所带来的的消耗
8、运行期多态和编译期多态
运行期多态,接口是显性的,多态,通过虚函数实现,发生于运行期
编译器多态,接口是隐形的,模板,通过具现化和函数重载,发生在编译期间
9、使用empty,而不是使用size()
empty直接检查标记节点,话费的时间实常数,size通过迭代器的距离来获取元素的个数,花费的时间是线性的
10、使用swap技巧来减少vector多余的容量
vector<T>().swap(test)
也可以用string().swap(s)
11、关联容器判断等价还是相等
1、相等,是==
2、等价,是operator<,等价是判断一个有序区间中对象值的相对位置
12、stable_sort是稳定排序
当容器中的数据出现两个相等的情况时,使用stable_sort排序,不会出现死机问题,sort是快速排序,是不稳定的,对于相等的元素sort可能改变顺序,但是stable_sort不会改变原有顺序
13、list有专门的sort排序
list的迭代器是双向迭代器,sort算法要求是随机访问迭代器,容器的成员函数优先于同名的算法
1、可以获得对数的时间性能,而不是线性时间的性能
2、STL算法以相等性来判断两个对象是否具有相同的值,关联容器需要使用等价来进行相同性测试
3、STL算法考虑的是Key和Value都匹配上,成员函数往往速度更快
14、STL删除元素时,需要在remove之后调用erase
remove,两个参数制定了需要进行操作的区间,但是并没有将容器中的元素删除,同时返回操作区间的end迭代器的位置,在使用erase函数,删除需要删除的区间