分享

C++标准库的学习笔记

 guitarhua 2013-12-16
C++标准库的学习笔记
    C++标准库是个极为庞大的体系,因此面面俱到的介绍几乎是不可能的。而且任何一个系统都有其复杂的一面,我觉得即使是只介绍 C 的标准库其工作量也是巨大的,所以我这次整理的内容只也是从宏观入手。介绍 C++标准库相关细节的文章(或书籍)有不少,不同的文章也有各自的侧重点。我觉得了解C++标准库有助于加深对 C++ 的理解,因此我想整理一下自己的学习心得,也可以使大家从另一个角度认识一下 C++。因为我曾经看到有位版主也说过 string 类的底层是 vector<char> 这么不靠谱的话,所以才觉得介绍介绍这些方面的知识也挺有意义。
    语法并不是一个语言的全部,学习一门语言的精力经常是放在学习它的库上,或是内置库,或是扩展库,第三方库。不过精力应该放在学习库的用法上,而不是掌握库的结构或实现,所以我这篇文章准备谈及的内容也比较偏,不过依然有可能激发一些人的学习兴趣。大家应该了解,语法像 C++ 这般复杂的语言是绝无仅有的,很多简单的语言,只要愿意,半小时就能学尽它的语法,并且这种语言依然很有效。(对于熟悉 Linux 的人来说,一个很好的例子是 bash,即使它对 sh 的语法做了如此之多的扩展,你仍能在半小时之内掌握它的全部语法。)
    我这么说的意图是,即使通晓C++的语法(先不论是否能够通晓)也许也无法理解它的设计哲学。标准库也是 C++ 的一个很重要的组成部分,这是我觉得这篇文章确实值得一写的另一个原因。

标准库的组成:
    前言就到此为止。从最宏观的层面上看,C++标准库由十个部分组成:语言支持、诊断、通用工具、字符串、本地化、容器、迭代器、通用算法、数值算法和I/O。相信其中有很多是大家已经熟知的了,我也不会详细地介绍每个部分。关于容器、迭代器和算法相关的细节与原理,我认为参考侯捷老师的《STL源码剖析》是非常适宜的。虽然其中也有少量的错误的,但无法掩盖它的价值。相信我的这篇文章错误会更多,因为我对 C++ 确实知之甚少。

名空间std:
    所有的标准库定义的东西,除了宏、operator new 和 operator delete(马上我就会解释宏,而 new 和 delete 我将在介绍语言支持的时候介绍)都在 std,或者是内嵌在 std 里的名空间里面。
(也许大家不熟悉这种语法。下面的例子定义了两个名空间 outer 和 inner。inner 就是内嵌在 outer 里的。它们都独立于 std:
程序代码:
#include <iostream>
using std::cout;
using std::endl;

namespace outer {
    int a = 5;
    namespace inner {
        int a = 10;
    }
}
using namesapec outer;

int main()
{
    cout << a << endl;     // 输出:5
    cout << inner::a << endl; // 输出:10

    return 0;
}

)

头文件组成:
    C++ 标准库一共包含 33 个C++ 头文件:
<algorithm>, <bitset>, <complex>, <deque>, <exception>,  <fstream>,  <functional>,
<iomanip>, <ios>, <iosfwd>, <iostream>, <istream>, <iterator>,  <limits>,  <list>,
<locale>, <map>, <memory>, <new>, <numeric>, <ostream>, <queue>, <set>, <sstream>,
<stack>, <stdexcept>, <streambuf>, <string>, <strstream>,  <typeinfo>,  <utility>,
<valarray>, <vector>
和 18 个 C的标准库头文件:
<cassert>, <cctype>, <cerrno>, <cfloat>, <ciso646>, <climits>,  <clocale>,  <cmath>,
<csetjmp>, <csignal>, <cstdarg>, <cstddef>, <cstdio>, <cstdlib>, <cstring>, <ctime>,
<cwchar>, <cwctype>
    再次强调,所有的头文件都不以 .h 结尾。且除了宏以外,都定义在名空间std 里。宏是预处理对象,它不在名空间里是件很自然的事情,因为对宏的处理发生在编译之前。但这经常引起混淆,比如 errno (在 <cerrno> 里)就是一个宏。如果以为它是一个 int,从而使用 std::errno 这样的语句,那么就会出错,而且往往编译器报的错误看上去还非常古怪。另外有一些看上去像函数的宏也常常引发问题,不过这个概率要小一些,因为在 C 的实践中,它们也老出问题,从而累积了不少经验。

以下划线开始的标识符:
    标准规定,以双下划线开始(如 __USE_GNU)或者以单下划线开始并跟一个大写字母(如_M_gcount,这两个标识符出自 gcc)的名字是保留给实现的(也就是说标准库里不用这样的名字);任何以单下划线开始的名字是保留给实现和标准库的。所以我们应当避免自己定义这样的名字,这样可以使阅读代码的人很清楚,一但下划线出现,必然是在引用标准库或者实现的特性。

库函数的可重入性:
    标准并没有规定 C++ 的库函数是否是可重入的,这就需要程序员自己斟酌可能出现的情况。

    OK,对标准库的概述就是这样,是不是感觉也很简单?我希望我可以做到深入浅出。当然这只是个开始,我马上准备介绍的是语言支持。如果有时间,我还准备陆续介绍一下标准库的那其它组成部分。我很乐意看到大家提出意见或建议。

[ 本帖最后由 pangding 于 2012-4-3 09:14 编辑 ]
 
语言支持(已完成,非常长):
http://bbs./thread-364885-1-1.html
诊断(已完成):
http://bbs./thread-366209-1-1.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多