Advertisement

C++ Standard Library

阅读量:

C++ Standard Library

注:此段主要为学习笔记材料的记录,
大部分内容源自参考书籍,
其中一些知识点和图片来自另一本参考书。
具体参考信息请参阅下方参考

C++98中新支持的语言特性

  1. 非类型的模板参数template<std::size_t N> class bitset;
  2. 默认类型的模板参数template<typename T, typenameAllocator = std::allocator<T>> class vector
  3. 关键字用于表示后续标识符为类型。
  4. 支持成员模版函数(member template functions),然而这些成员模版函数不能为纯虚函数(pure virtual functions)。
  5. 支持嵌套类模版(nested class templates)。
  6. 基本类型的显式初始化(explicit initialization)int x = int(); 该特性确保任意类型的值都有一个初始化的默认值。

C++11中新支持的语言特性

  1. 模板尖括号之间不再需要空格符了,vector<list<int>> // since c++11

  2. 关键字nullptr // since c++11

  3. 关键字auto // since c++11,自动类型推导,从变量的初始化器中推导出该变量的类型。

  4. c++11支持统一的初始化形式,使用大括号。注意的是,{}初始化不能进行类型缩小转换。例如int x{2.0}; // is wrong

  5. c++11支持初始化列表,如int std::vector<int> v{2, 3, 4, 65}; // initializer list。注意,如果一个类声明了
    显示构造函数,则不可使用初始化列表。

  6. C++11采用了foreach循环语法。

  7. C++11引入了move semantics和rvalue forwarding机制。其核心在于,在值传递时不再复制数据对象本身的数据内容(即对象的内容不会被拷贝),而是直接引用其资源。

复制代码
    namespace std {
    template<typename T, ...> 
    class set {
    public:
        ... insert(const T& x); // for lvalues, copies the value
        ... insert(T&& x);      // for rvalues, moves the value
    
    };
    }
  1. 返回一个非静态的局部对象的右值引用时错误的。
  2. c++11支持原生字符串(raw string)和多字节/宽字节字符串(multibyte/wide-character string)。
    R"(\ n)"; // raw string, begin with R(", and end with )"。为了能够在原生字符串中使用)",需要使用
    分隔符。原生字符串的完整语法是R"delim(...)delim",其中delim是一个至多16个基本字符的字符序列,并且delim中
    不能有反斜杠backslash,空白符whitespaces,与括号parentheses。如:
复制代码
    R"nc(a\
    b\nc()"
    )nc";
    
    //等价于
    "a\ \n   b\ nnc()"\n     "

多字节/宽字节字符串字面值

复制代码
    u8定义UTF-8字符串字面值
    u定义cha16_t字符串字面值
    U定义char32_t字符串字面值
    L定义wchar_t字符串字面值

C++提供关键字noexcept用于指定一个函数不出错或无需处理错误(faults);一旦出现错误就必须在其定义域内进行处理。需要注意的是,在C++中实现这种功能的方式并不是通过在编译阶段进行错误检测(compilation-time fault checking),而是依赖于运行时机制(runtime checking)。这些检测通常会导致编译器生成额外代码以实现相关功能,并且这种机制可能会干扰到某些优化过程(optimization)。对于泛型程序而言(generic programming),由于其复杂性特点,在分析模板参数操作可能导致什么类型的错误方面往往无法给出明确结论

  1. 关键字constexpr使表达式能过在编译期被计算出来。

  2. c++11支持可变参数模板。

复制代码
    template<typename T, typename... Types>
    void Test(T& x, Types& ... args) {
    ...
    }

在变参模板内,使用sizeof…(args),会返回参数的数目。

  1. c++11使用模板的别名
复制代码
    template<typename T>
    using Vec = std::vector<T>;
    Vec<int> vec;
    // 等价于
    std::vector<int> vec;

C++11提供默认模板参数功能;
C++11语言允许使用局部类型作为模板参数;
C++11标准定义了内部链接函数作为模板参数的可能性。

C++11引入了Lambda表达式。
[capture-list] (params) mutable exception attribute -> ret {body}
其中:

  • capture-list为通过逗号分隔的方式定义的捕获列表;
  • [a, &b]中a按值形式被捕获、b按引用形式被捕获;
  • [this]用于按值形式捕捉This指针;
  • [&]用于按引用形式捕捉所有自动变量;
  • [=]用于按值形式捕捉所有自动变量;
  • []表示未捕捉任何数值。

C++11新增了关键字decltype,并且编译器能够推导出表达式的类型。\n\n新的函数声明语法是关于如何指定这些类型的描述。

复制代码
    template<typename T1, typename T2>
    auto add(T1 x, T2 y) -> decltype(x + y);

支持作用域枚举(这个是我搞错了,作用域枚举是c++98/03就支持的)

复制代码
    enum struct|class name {enumerator = constexpr, enumerator = constexpr, ...};
    enum struct|class name : type {enumerator = constexpr, enumerator = constexpr, ...};
  1. c++11支持新的基本数据类型:char16_t, char32_t, long long, std::nullptr_t

C++中都有哪些命名空间

复制代码
    std
    std::tr1
    std::rel_ops
    std::chrono
    std::placeholders
    std::regex_constants
    std::this_thread
    std::posix  // 未使用,保留

C++异常继承框架

异常继承框架

语言级支持的异常类
bad_cast:包含于头文件<typeinfo>内。运行时若dynamic_cast操作失败会导致该异常发生。
bad_typeid:包含于头文件<typeinfo>中。运行时若typeid参数为零或为空指针将触发该异常事件。
bad_exception:定义于头文件<exception>中用于处理不可预知的错误类型。一旦函数抛出一个非标准规范中的异常后续将调用unexpected()函数引发bad_exception事件。需要注意的是,在C++11标准中已经弃用使用异常规范机制。

逻辑相关错误(logic-related error)
包括域错误(domain error)、无效参数(invalid argument)、长度相关错误(length-related error)以及超出范围(out-of-range)等类型。
其中:

  • 长度相关错误(length-related error):通常指程序试图操作超出数组或字符串长度的数据。
  • 无效参数(invalid argument):指函数或操作被调用时传递的参数不符合其预期类型或范围。
    未来错误(future error):由C++11及其以后版本引入的一种新异常类型。
    该异常类主要用于处理与未来事件相关的操作结果不一致的情况,
    例如未绑定的 futures 或未初始化的对象引用等。

运行时错误(runtime_error)
range_error:当试图将范围转换为目标类型时无法完成表示。在C++标准库中只有std::wstring_convert::from_bytesstd::wstring_convert::to_bytes会抛出该异常。定义在头文件<stdexcept>中。
overflow_error:用于报告算术运算溢出(上溢)错误,在标准库中只有std::bitset::to_ulongstd::bitset::to_ullong会抛出该异常。定义在头文件<stdexcept>中。
underflow_error:定义在头文件<stdexcept>中。
system_error:用于报告由于操作系统引起的错误,该异常的抛出通常是由并发操作所引起的,在C++11以后开始支持。
定义在头文件<system_error>中。
bad_alloc:由全局new操作符引发的异常错误,在头文件<new>中定义。
bad_array_new_length:继承自bad_alloc,在C++11以后提供的一种异常类,在new分配一块内存时大小超出实现所设定的限制时会抛出该异常。
bad_weak_ptr:定义于头文件<memory>中,在C++11以后开始支持的一种异常类型;当将一个由std::weak_ptr转换为std::share_ptr时如果被转换对象已删除,则会抛出此异常.
bad_function_call:定义于头文件中;自C++11起支持的一种异常类型;当函数对象为空对象时调用该对象会导致此异常.

Callable

Callable类型的对象能够执行特定操作,并且其定义涉及std::function, std::bind以及std::thread::thread等相关类型体系。此外,在这种体系中, callable类型的对象具体表现为:它可以是一个普通的函数对象;也可以是通过指针或引用形式指向某个函数;还可以是一个成员函数相关联的对象;甚至也可以是一个与数据成员直接相关的对象。

Utilities

template<typename T1,typename T2> struct pair; (<pair>)
template<typename... Types> class tuple;(<tuple>)
template<typename T,typename Deleter=std::default_delete<T>> class unique_ptr; (<memory)
通过共享指针机制实现对象引用的有效管理(<memory)
共享指针对象只能在构造时创建一组实例,并不能为同一对象创建多个共享指针实例(<memory)
单个对象的共享指针实例只能被用于构造新的共享指针对象(<memory)
引入了enable_shared_from_this类以增强shared_ptr的功能(<memory>) 提供了default_delete模板函数及其扩展形式()
详细说明了基本数据类型的最小内存占用空间情况(<limits>)
新增于C++11的标准库组件中提供了丰富的编译时类型信息工具(<type_traits>)
通过引用包装器实现对函数式的封装与操作(<functional>)
算法库中的序列操作功能包括不可逆操作、可逆操作以及集合运算等基础功能(<algorithm>) 需要注意的是remove算法不会真正删除元素而是移动迭代器位置(不影响容器实际大小)()
C++11标准库新增了ratio编译时分数算术运算组件(<ratio>) C++11标准库提供了新的高精度时钟组件() `

The Standard Template Library

STL通过实现对数据与其操作的分离管理,使数据被容器所管理,并使操作被算法所执行;迭代器则充当了连接算法与容器的作用

STL 容器分类:
序列容器:包括 array、vector、deque 和 list 等数据结构;它们大多基于数组或链表结构设计。
关联容器:如 set 和 multiset 使用红黑树实现;map 和 multimap 则采用相同的数据结构以实现快速查找功能。
无序关联容器:unordered_set 和 unordered_multiset 采用哈希表实现;unordered_map 和 unordered_multimap 则基于开放寻址技术以提高查询效率。
容器适配器:stack、queue 和 priority_queue 分别对应于栈、队列和优先级队列的接口定义;它们提供了基本操作功能而无需具体数据存储结构支持。

STL 迭代器分类:
可前向遍历器、双向遍历器及随机访问遍历器;
仅支持前向操作的输入遍历器与仅允许前向操作的输出遍历器。

迭代器分类 功能 提供该迭代器的类、函数或数据结构
OutputIterator 前向写 ostream,inserter
InputIterator 一次前向读 istream
ForwardIterator 前向读 forward_list, unordered associative containers
BidirectionalIterator 双向读 list,associative containers
RandomAccessIterator 随机读 array,vector,deque,string,C-style array

流类迭代器包含四种不同类型的实例:输入流读取迭代器、输出流写入迭代器、输入缓冲流读取迭代器以及输出缓冲流写入迭代器

迭代器适配器:

作为容器的元素需具备以下三个要素:
支持复制或迁移;支持赋值;可以被销毁;

注意c++标准模板库仅支持值语义。

当向量进行内存重新分配时,在原有向量中的元素的引用、指针以及迭代器将变得无效。
特别地,在实现过程中针对vector<bool>进行了优化设计,并且显著减少了内存占用。

deque的内部实现可能基于多种内存块布局设计。其中一些内存块专门用于前向增长操作,另一些则用于逆向增长操作。

注意list的splice成员函数,是在指定的位置的前面插入元素的。

在设计自定义关联容器排序规则时,请确保满足以下严格弱序化条件:

  • 反对称性要求:若元素x小于元素y,则元素y不可能小于元素x;
  • 传递性规定:如果元素x小于元素y且元素y小于元素z,则必须保证元素x也小于元素z;
  • 反自反性规定:任何元素x与其自身之间的小于关系必须被排除;
  • 相等性的传递性质要求:当无法比较两个元素之间的顺序(即两者互不大于对方)时,并且同样无法将其中第二个与第三个进行比较,则必须无法将第一个与第三个进行比较。

函数对象,即在类中重载了operator ()

输入输出流:
istream: 读取数据的技术基于模板库basic_istream
ostream: 写入数据的技术基于模板库basic_ostream
全局流对象:通常指代cin、cout、cerr、clog等标准库对象
继承关系:如图所示

流继承关系

其它的功能,在遇到的时候再参考帮助文档与其他资料学习。

1. (《The C++ Standard Library 2nd edition》,Nicolai M.Josuttis)
2. cpp

全部评论 (0)

还没有任何评论哟~