C++标准程序库

openkk 13年前

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安插元素如果失败,都无法做到完全恢复.如果元素的型别保证拷贝动作不抛异常,则所有加诸于改元素身上的操作都能够保证要么成功,要么就毫无影响.