《The C++ Standard Library》读书笔记

本来以为仅看《Generic Programming and the STL》和STL的代码就可以把STL搞得比较透彻的,结果在看deque的代码实现时,很难看懂。看看了这本书对应的deque,讲得比《Generic Programming and the STL》清楚一些,至少还有图呢,所以,打算对于STL的学习,还需要看看这本书,要是有《STL源码剖析》这本书,估计看代码就更容易了。

先把这三本书加代码看完,再决定是否还需要看其他的STL书籍。

 

注:以下仅仅记录《Generic Programming and the STL》中没有提到的部分。

 

C++Standard Library, The: A Tutorial and Reference

 

C++Standard Library provides a set of common classes and interfaces that greatlyextend the core C++ language. The library, however, is not self-explanatory. Tomake full use of its components-and to benefit from their power-you need aresource that does far more than list the classes and their functions.

 

TheC++ Standard Library not only provides comprehensive documentation of eachlibrary component, it also offers clearly written explanations of complexconcepts, describes the practical programming details needed for effective use,and gives example after example of working code.

 

Thisthoroughly up-to-date book reflects the newest elements of the C++ standardlibrary incorporated into the full ANSI/ISO C++ language standard. Inparticular, the text focuses on the Standard Template Library (STL), examiningcontainers, iterators, function objects, and STL algorithms. You will also finddetailed coverage of special containers, strings, numerical classes,internationalization, and the IOStream library. Each component is presented indepth, with an introduction to its purpose and design, examples, a detaileddescription, traps and pitfalls, and the exact signature and definition of itsclasses and their functions. An insightful introduction to fundamental conceptsand an overview of the library will help bring newcomers quickly up to speed.

 

Comprehensive,detailed, readable, and practical, The C++ Standard Library is the C++ resourceyou will turn to again and again

 

我曾经把STL的学习比喻为三个境界:

第一境界:熟用STL

第二境界:了解泛型技术的内涵与STL的学理乃止实作

第三境界:扩充STL

不论哪一个阶段,你都能从本书获得不同程度的帮助。

 

程序库中几乎所有东西都被设计为template形式。不支持template,就不能使用标准程序库。

 

所谓templates,是针对"一个或多个未明确的数据类型"所撰写的函数或类.

 

Template并非一次编译便生出适合所有型别的代码,而是针对被使用的某个类型进行编译.也就是说,在每个使用模板的cpp文件中,都必须知道模板函数或类的具体定义,所以模板函数或类的定义全部是放在头文件中的,对于所有的函数,都必须定义成内联的,否则编译通不过的.

总之,模板函数或类都是定义在头文件中的,不像其他的函数或类分为声明(在头文件中)和定义(在源文件中).

template<class T>

inlineconst T& max(const T& a, const T& b)

{

    return a < b ? b : a;

}

 

非类型模板参数

即用具体的某个常量代替定义中的默认参数

bitset<32>flags32;

 

默认模板参数

即如果没有指定具体的参数类型的话,就用默认的.

template<class T, class container = vector<T> >

classMyClass;

 

模板成员函数

classmember funciton可以是个template,但这样的member template既不能是virtual, 也不能有缺省参数.

classMyClass

{

    template <class T> void f(T);

};

 

注意区分异常处理和错误处理

到目前为止我好像还没有真正能够区分开?

 

4通用工具

pair

用处:

凡需要将两个值视为一个单元的场合(例如必须"返回两个值"的某函数),就最好用它,不用我们自己另外定义结构了.

注:但是这个东西平常我们好像用得不多,如果需要返回多个值,我们都是用引用参数的方式完成,以后可以关注一下,看是否可以改善一下代码

例:

//utility_pair.cpp

//compile with: /EHsc

#include<utility>

#include<map>

#include<iomanip>

#include<iostream>

 

intmain( )

{

   using namespace std;

 

   // Using the constructor to declare andinitialize a pair

   pair <int, double> p1 ( 10, 1.1e-2 );//用法一

 

   // Compare using the helper function todeclare and initialize a pair

   pair <int, double> p2;

   p2 = make_pair ( 10, 2.22e-1 ); //用法二

 

   // Making a copy of a pair

   pair <int, double> p3 ( p1 );

 

   cout.precision ( 3 );

   cout << "The pair p1 is: ( "<< p1.first << ", "

        << p1.second << ")." << endl;

   cout << "The pair p2 is: ( "<< p2.first << ", "

        << p2.second << ")." << endl;

   cout << "The pair p3 is: ( "<< p3.first << ", "

        << p3.second << ")." << endl;

 

   // Using a pair for a map element

   map <int, int> m1;

   map <int, int>::iterator m1_Iter;

 

   typedef pair <int, int> Map_Int_Pair;

 

   m1.insert ( Map_Int_Pair ( 1, 10 ) ); //用法三

   m1.insert ( Map_Int_Pair ( 2, 20 ) );

   m1.insert ( Map_Int_Pair ( 3, 30 ) );

 

   cout << "The element pairs of themap m1 are:";

   for ( m1_Iter = m1.begin( ); m1_Iter !=m1.end( ); m1_Iter++ )

      cout << " ( " <<m1_Iter -> first << ", "

           << m1_Iter -> second<< " )";

   cout  << "." << endl;

 

   // Using pair as a return type for afunction

   pair< map<int,int>::iterator, bool> pr1, pr2;

   pr1 = m1.insert ( Map_Int_Pair ( 4, 40 ) );

   pr2 = m1.insert ( Map_Int_Pair (1, 10 ) );

 

   if( pr1.second == true )

   {

      cout << "The element (4,40)was inserted successfully in m1."

           << endl;

   }

   else  

   {

      cout << "The element with akey value of\n"

           << " ( (pr1.first) ->first ) = " << ( pr1.first ) -> first

           << " is already in m1,\nso the insertion failed." << endl;

   }

 

   if( pr2.second == true )

   {

      cout << "The element (1,10)was inserted successfully in m1."

           << endl;

   }

   else  

   {

      cout << "The element with akey value of\n"

           << " ( (pr2.first) ->first ) = " << ( pr2.first ) -> first

           << " is already in m1,\nso the insertion failed." << endl;

   }

}

 

pair之间的比较//用法四

 

auto_ptr

注意,auto_ptr<>不允许你使用一般指针惯用的赋值初始化方式.你必须直接使用数值来完成初始化:

std::auto_ptr<ClassA>ptr1(new ClassA);  //OK

std::auto_ptr<ClassA>ptr2 = new ClassA; //ERROR

 

auto_ptr拥有权的转移

绝对不应该出现多个auto_ptr同时拥有一个对象的情况.怎么保证呢?

除了上面的做法,还有:

在拷贝函数发生或赋值操作函数发生时将拥有权转移到新的auto_ptr对象.

比如

std::auto_ptr<ClassA>ptr1(new ClassA);

std::auto_ptr<ClassA>ptr2(ptr1); //此后,ptr2拥有了那个new出来的对象,而ptr1不再拥有它.

对于赋值操作也是如此

std::auto_ptr<ClassA>ptr2;

ptr2= ptr1; //此后,ptr2拥有了那个new出来的对象,而ptr1不再拥有它.

如果ptr2在之前已经拥有其他对象了,赋值操作会先把以前的delete掉,再拥有新的对象.失去拥有权的auto_ptr对象维护的对象指针将变成NULL,如果你再使用它的话,程序就挂了.

记住了上面的拥有权转移,其他的就好理解了,比如将auto_ptr做为参数传递:

如果某个函数就是对象的终点,即这个函数处理完之后,对象就可以销毁了,那么我们可以

voidsink(std::auto_ptr<ClassA>); //现在这个临时参数变量就拥有了所有权,函数一返回就对象就销毁

如果某个函数是对象的诞生地,那么可以

std::auto_ptr<ClassA>f()

{

    std::auto<ClassA> ptr(new ClassA);

    ...

    return ptr;

}

我们一定要防止"不经意转移拥有权"所带来的危险.比如

我们要打印一个对象的内容,不能这样定义函数

voiddoPrint(std::auto_ptr<int> ptr); //如果不是终点就会造成错误,本来我们不想销毁对象的,现在确销毁掉了.

voiddoPrint(const int* ptr); //只能这样定义

到时根据get函数获取到对象指针穿进函数就行了,这样就不会发生拥有权的转移.

你也不能定义成引用,那样违反了auto_ptr的规则;

intmain( )

{

   auto_ptr<Int> pi ( new Int( 5 ) );

   pi.reset( new Int( 6 ) ); //先销毁掉老的,再生成新的,即拥有新的

   Int* pi2 = pi.get ( ); //不会失去所有权

   Int* pi3 = pi.release ( ); //会失去所有权

   if (pi2 == pi3)

      cout << "pi2 == pi3"<< endl;

   delete pi3;

}

还有一个注意的地方是auto_ptr不能应用于new出来的数组,因为它采用的是delete,而非delete[].

std::auto_ptr<int>p1(new int[10]); //不要这样

注:

这个东西我们用得不多,因为不熟,其实也挺好使得,只要我们用得都是拷贝或者赋值,那么那个指针就一直传下去,直到销毁,即重点在于分清函数是否是对象的终点,这样就可以确定函数的参数.

以后多使使这个东东.

 

 

5标准模板库

 

Chapter6. STL Containers

 

6.1Common Container Abilities and Operations

 

以标准输入装置完成初始化操作:

    //read all integer elements of the dequefrom standard input

    std::deque<int>c((std::istream_iterator<int>(std::cin)),(std::istream_iterator<int>()));

(注意,这个代码在VC6.0中是编译不过的,但在VS2005中是可以的。)

注意,不要遗漏了涵括“初始化参数”的那对“多余的”括号,否则这个表达式的意义会迥然不同,肯定让你匪夷所思,你会得到一堆奇怪的警告或错误。以下是不写括号的情形:

    std::deque<int>c(std::istream_iterator<int>(std::cin),std::istream_iterator<int>());

 

Inthis case, c declares a function with a return type that is deque<int>.Its first parameter is of type istream_iterator<int> with the name cin,and its second unnamed parameter is of type "function taking no argumentsreturning istream_iterator<int>." This construct is validsyntactically as either a declaration or an expression. So, according tolanguage rules, it is treated as a declaration. The extra parentheses force theinitializer not to match the syntax of a declaration.[3]

 

 

6.3Deques

 

与vector相比,deque功能上的不同之处在于:

1.在对内存区块有所限制的系统中(例如PC系统),deque可以包含更多元素,因为它使用不止一块内存。因此,deque的max_size()可能更大。

2.deque不支持对容量和内存重分配时机的控制。特别要注意的是,除了头尾两端,在任何地方安插或删除元素,都将导致指向deque元素的任何pointer、references、iterators失效。不过,deque的内存重分配优于vector,因为其内部结构显示,deque不必在内存重分配时复制所有元素。

3.deque的内存区块不再被使用时,会被释放。deque的内存大小是可缩减的。不过,是不是这样做,以及究竟怎么做,由实作版本定义之。

 

deque的各项操作只有以下数点和vector不同:

1.deque不提供容量操作(capacity()和reserve())。

2.deque直接提供函数,用以完成头部元素的安插和删除(push_front()和pop_front())。

其他操作都相同,这里不再重复。

 

6.4Lists

 

6.5Sets和Multisets

 

 

 

 

The Best-Selling Programmer Resource–Now Updated for C++11 The C++ standard library provides a set of common classes and interfaces that greatly extend the core C++ language. The library, however, is not self-explanatory. To make full use of its components - and to benefit from their power - you need a resource that does far more than list the classes and their functions. The C++ Standard Library - A Tutorial and Reference, 2nd Edition describes this library as now incorporated into the new ANSI/ISO C++ language standard (C++11). The book provides comprehensive documentation of each library component, including an introduction to its purpose and design; clearly written explanations of complex concepts; the practical programming details needed for effective use; traps and pitfalls; the exact signature and definition of the most important classes and functions; and numerous examples of working code. The book focuses on the Standard Template Library (STL), examining containers, iterators, function objects, and STL algorithms. You will also find detailed coverage of strings, concurrency, random numbers and distributions, special containers, numerical classes, internationalization, and the IOStreams library. An insightful introduction to fundamental concepts and an overview of the library will help bring newcomers quickly up to speed. A comprehensive index will support the C++ programmer in his/her day-to-day life. The book covers all the new C++11 library components, including Concurrency Fractional arithmetic Clocks and Timers Random numbers and distributions New smart pointers Regular expressions New STL containers, such as arrays, forward lists, and unordered containers New STL algorithms Tuples Type traits and type utilities The book also examines the new C++ programming style and its effect on the standard library, including lambdas, range-based for loops, and variadic templates. An accompanying Web site, including source code, can be found at http://www.josuttis.com/.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值