C++标准程序库
5627 点击·0 回帖
![]() | ![]() | |
![]() | 1. 如果要把一个template中的某个标识符号指定为一种型别,就算意图显而易见,关键字typename也不可或缺,因此一般的规则是,除了以typename修饰之外,template内的任何标识符号都被视为一个值而非一个型别. 2. 类的成员函数可以是个template,但这样的成员函数既不能是virtual也不能有缺省参数. 3. 如果程序允许我们为成员函数提供不同的template型别,就可以放宽”必须精确吻合”这条规则:只要型别可被赋值,就可以被当做上述成员模板函数的参数. 4. 通过explicit,我们可以禁止”单参数构造函数”,被用于自动类型转换.其中有对应的一个词implicit.这个词不是C++关键字(因为C++默认的是隐式转换的).这里这总结类似的关键字: volatile.使用这个关键字以后,优化器在用到这个变量时必须每次都小心的重新读取这个变量的值,而不是使用保存在寄存器中的备份. 5. auto_ptr中拥有权的转移情况: ◆ 某函数是数据的终点. Voidskin(std::auto_ptr<ClassA>); ◆ 某函数是数据的起点 此外,不能以by reference方式传递auto_ptr.(无法预知拥有权是否被转交) 就特性而言,constauto_ptr类似于常数指针(T*const p).而非指向常数d的指针.(const T* p) 如果auto_ptr在整个生命期内都不必改变其所指对象的拥有权,就可以使用const auto_ptr const std::auto_ptr<int> p(new int(42)); std::auto_ptr<int> q(new int( -11 )); *p = *q;//此时只是q指向了新的地址.所有权并没有通过q转移. 6. const 成员函数.其对象的成员不能改变. 因此不难得出以下结论: ◆const 成员函数即可以供const对象调用,也能供非const对象调用,此时const不能改变非const对象的成员 ◆ const 对象不能调用非const 成员函数(因为非const对象可能会改变const对象) ◆非const函数不能调用const函数,反之可行 Mutable关键字:在const成员函数中也能改变mutable修饰的变量 7. 前置式递增(++pos)与后置递增相比,前者效率高.因为需要额外的临时对象.所以,在一般情况下使用前置 8. 在使用set和map时,要注意排序问题.(关联容器)它们的实现是以树作为基本结构来存储. 9. 三类插入迭代器: ◆ back inserter:利用push_back操作向容器插入.适合的容器:vector,deque,list ◆ front insert:利用push_front操作向容器插入.适合的容器:deque,list.(相当于链表前插) ◆ general insert:向第二个参数的位置前插入新的元素. Inserter(contain,contain.begin()) 相当于front_insert Inserter(contain,contain.end()) 相当于back_insert 10. 更易型算法(remove,resort,modify)不能作用于关联式容器,因此时会改变某位置上的”值”(指键值).另外在选用算法的同时,首先应当确定是否可以利用容器的成员函数来代替. 11. 如果要把一个template中的某个标示符指定为一种类型,就算意图显而易见,关键字typename也不可或缺,因此C++的一般规则是,处理以type修饰之外,template内的任何标示符都被视为一个值,而非一个型别. 举例: class A { public: typedef int SubType; private: intvalue; }; template<class T> class MyClass{ typedef T::SubType * ptr; // typedef typename T::SubType * ptr; }; int main() { MyClass<A> my_cls; } 编译器(vs2010)报错: error C2143: 语法错误 : 缺少“;”(在“*”的前面). 编译器好像并不认识SubType.这就是上面所说的把其当做为一个值,而非类型.加上typename就ok了. 11. STL容器元素必须满足的三个基本要求: ◆ 必须可透过copy构造函数进行复制. ◆ 必须可以透过assignment操作符完成赋值动作. ◆ 必须可以透过析构函数完成销毁动作. 解释一点:我们平日里经常会写一个类的容器,但是,类里面没有看到什么copy,assignment什么的.为什么程序还能正常运行? 举例: #include <iostream> #include <set> using namespace std; class A { public: A(intiVlaue ):m_iValue( iVlaue ){} private: intm_iValue; }; int main() { set<A> coll; system("pause"); return0; } 关键在于编译器会在这种情况下帮我们合成自己的赋值和复制操作. 其他的需要满足特殊情况的条件: ◆ 对顺序容器,元素的默认构造函数必须可用 ◆ 对于某些特殊动作,必须定义operator==以执行相等的测试. ◆ 在关联容器中,元素必须定义排序准则,这里主要是定义<. 12. C++标准库对STL做出如下保证: ◆ 所有以节点来实现基础的容器(list,set,multiset,map,multimap),如果及诶单构造失败,容器保持不变.移除节点的容器保持不会失败.然而如果是对关联式容器插入多个元素,为保证已序性,失败时无法完全恢复原状.对插入单一元素操作,支持要么成功,要么原先的容器不受任何影响.此外,所有擦除操作(无论数量多少)肯定成功. 对list,就算插入多个元素,也属于安全操作,实际上,处理remove,remove_if,merge,sort,unique之外,要么成功,要么不受任何影响. ◆ 所有以array为构造基础的容器如vector,deque安插元素如果失败,都无法做到完全恢复.如果元素的型别保证拷贝动作不抛异常,则所有加诸于改元素身上的操作都能够保证要么成功,要么就毫无影响. | |
![]() | ![]() |