【C++primer】一学期阅读笔记

参考文献(References)

[1] Stanley B.Lippman,Josee Lajoie,Barbara E.Moo.C++ Primer 中文版(第5版)[M].王刚,杨巨峰,北京:电子工业出版社,2013.9


这一学期看了《C++ Primer》。把有用的句子记了下来。今天把它们录入电脑,总结如下。


1.1:    访问main的返回值方法 $echo$? $echo %ERRORLEVEL%
1.2:    iostream → istream + ostream
1.3:    调试打印语句保持一直刷新,程序崩溃会让输出保持在缓冲流中
1.4:    UNIX系统中文件结束符用CTRL+D
1.5:    type error
1.6:    declaration error
1.7:    修正一个错误后立即调试代码
1.8:    一旦选择了一种风格,就要坚持使用
1.9:    bool(ud)、char(8)、wchar_t(16)、char16_t(16)、char32_t(32)、short(16)、int(16)、long(32)、long long(64)、float(6)、double(10)、long double(10);
1.10:    long long在C++11中定义
1.11:    int下取整 == short long下取整==int long long下取整==long
1.12:    可寻址的最小内存块称为字节(byte)
1.13:    存储的基本单元 字(word)
1.14:    字节由8bit构成,字则由32或64比特构成,也就是4或8字节
1.15:    float 1字 double 2字 long double 3~4个字 float 7有效位 double16有效位
1.16:    明确知晓数值不为负的时候,选用无符号类型
1.17:    算术表达式不要使用char或bool
1.18:    执行浮点数运算选用double
1.19:    超出符号类型范围的值:1继续工作,2崩溃,3垃圾数据
1.20:    2的32 = 4294967296
1.21:    (unsigned)10+(int)(-42) = 2的32次方-32
1.22:    (unsigned)10-(unsigned)42 = 2的32次方-32
1.23:    (unsigned)作循环,条件>=0为死循环
1.24:    --(unsigned)0 = 2的32-1
1.25:    带符号类型和无符号类型进行运算,有符号转无符号
1.26:    (unsigned)10 - (int)10=0
1.27:    (int)10 - (unsigned)10 = 0
1.28:    形如42的值——字面值常量
1.29:    从0开头的整数表示八进制、以0x或0X开头的代表十六进制数
1.30:    int month = 09
1.31:    \? \f \a
1.32:    \7响铃 \12换行符 \40空格 \0空字符 \115字符M \x4d(字符M)
1.33:    字符串字面值的实际长度比它的内容多1
1.34:    "\1234"→'\123'+'4'两个字符
1.35:    "\x1234"表示一个16位的字符
1.36:    对象是指一块能存储数据并具有某种类型的内存空间
1.37:    练习2.10
1.38:    extern int j//声明i而并非定义i
1.39:    extern包含初始值就不再是声明了
1.40:    全局变量多个文件共同使用,则用extern声明即可
1.41:    C++静态类型语言statically typed 类型检查 type checking
1.42:    不能连续出现两个下划线,不能以下划线紧连大写字母开头,函数体外的标识符不能以下划线开头
1.43:    变量名一般用小写字母、自定义的类名以大写开头
1.44:    alignas、register、alignof、decltype、reinterpret_cast、asm、auto、typeid、typename、enum、static_cast、char16_t、explicit、noexcept、char32_t、export、nullptr、volatile、wchar_t、constexpr、thread_local、const_cast
1.45:    and、bitand、compl、not_eq、or_eq、xor_eq、and_eq、bitor、not_or、xor
1.46:    scope作用域
1.47:    在对象第一次被使用的地方附近定义它是一种好的选择,因为这样做有助于容易找到变量的定义
1.48:    for(int i=0;i!=10;++i)执行几次?10,i = [0:9]
1.49:    复合类型compound type引用和指针
1.50:    (base type)+(declarator)
1.51:    右值引用 rvalue reference 左值引用 lvalue reference
1.52:    refers to global scopeblock scope
1.53:    引用必须被初始化
1.54:    引用一生只能绑定一个对象
1.55:    pointer指针
1.56:    解引用符(*)\
1.57:    int *p1 = nullptr,int *p2 = 0,int *p3 = NULL
1.58:    void* ① 可以存放任意对象的地址 ② 和别的指针作比较 ③ 作为函数的输入和输出
1.59:    int&r = 0 是错的
1.60:    int *const p2 = &i2 是对的
1.61:    const int &r = 0 是对的
1.62:    const int *const p3 = &i2 是对的
1.63:    const int *p1 = &i2
1.64:    const int &const r2 是错的
1.65:    const int *p 是对的
1.66:    在多个文件出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量
1.67:    添加extern在多个文件之间共享const对象
1.68:    const int &r1 = ci
1.69:    指向常量的指针,常量指针,常量const
1.70:    常量表达式const expression
1.71:    在编译过程中就可以得到结果
1.72:    使用constexpr类型由编译器来验证常量表达式
1.73:    算术类型,引用和指针都属于字面值类型
1.74:    自定义类不属于
1.75:    不能定义成constexpr 
1.76:    int null=0,*p=null;
1.77:    类型别名(type alias)
1.78:    typedef 同名化
1.79:    别名声明 alias declaration
1.80:    using SI = Sales_item,同义词
1.81:    SI item 指针常量和类型别名
1.82:    typedef char* pstring,const pstring cstr = 0,const char *cstr = 0
1.83:    前者表示指向了char的常量指针,后者表示指向了const char的指针
1.84:    auto自动分析表达式结果所属的类型
1.85:    auto一行申请多个变量的时候全部要一样
1.86:    decltype引入了第二种类型说明符
1.87:    decltype(f())sum = x,sum的类型就是函数的返回类型,不实际计算函数的返回值
1.88:    头文件一旦改变,相关的源文件必须重新编译以获取更新过的声明
END 20150921 星期一


2.1:    头文件保护符header guard
2.2:    #ifndef SALES_DATA_H …… #endif
2.3:    第一次包含时,#ifndef为真,即未包含该头文件,所以执行到#endif
2.4:    到了第二次包含时为假,所以就不导入该头文件了
2.5:    预处理变量名字全部大写
2.6:    string可变长字符串 vector可边长的集合
2.7:    using std::cin
2.8:    string s4(10,'c')
2.9:    用等号初始化一个变量叫拷贝构造化
2.10:    用括号初始化叫做直接初始化
2.11:    cin>>不读入换行符存在缓冲区
2.12:    string::size_type无符号类型的字,足够存放下string对象的大小。有string.size()就不要与int作计算了,避免unsigned和int混用
2.13:    标准库的名字总能在std::中找到
2.14:    cctype isalnum(c)字母数字 isalpha(c)字母 iscntrl(c)控制字符 isdigit数字 islower isprint可打印字符 ispunct标点符号 isspace空白 issupper大写字母 isxdigit十六进制数 tolower toupper
2.15:    for(auto c:string)cout< 2.16:    vector v5{a,b,c,……}
2.17:    vector ivec(10,-1)
2.18:    vector.push_back(i)
2.19:    v[n]
2.20:    for(auto &i:v){i*=i;}
2.21:    s.begin()返回指针
2.22:    begin()返回第一个元素
2.23:    end()返回最后一个元素的下一个元素(空)
2.24:    for(auto it = s.begin();it!=s.end() && !isspace(*it);++it)*it=toupper(*it);
2.25:    begin()和end()若为const常量则返回const_iterator否则返回iterator
2.26:    difference_type
2.27:    如果不清楚元素的确切个数 请使用vector
2.28:    自量常量表达式constexpr
2.29:    编译器扩展compiler extension
2.30:    由内向外 自右向左阅读
2.31:    cstddef定义了size_t表示内存中任意对象的大小
2.32:    int* e = arr[10]
2.33:    begin(int[])
2.34:    end(int[])
2.35:    两个指针相减的结果类型是ptrdiff_t
2.36:    strcmp比较p1==p2 0 p1>p2+ p1 2.37:    strcpy将p2拷贝到p1,返回p1
2.38:    strlen以'\0'空字符判断结尾
2.39:    c_str()
2.40:    无法保证c_str()指向的数组一直有效
2.41:    for(auto& row:ia)for(auto&col:row){}
2.42:    int i = 0 , cout< 2.43:    逻辑与&& 逻辑或|| 条件?: 逗号,明确规定了运算对象的求值顺序
END 20150928 星期一 P123


3.1:    如果改变了某个运算对象的值,在表达式其它的地方不要再使用这个值
3.2:    (-m)/n = m/(-n) = -(m/n)
3.3:    m%(-n) = m%n
3.4:    (-m)%n = -(m%n)
3.5:    (-m)%(-n) = (-m) % n = - (m%n)
3.6:    优先使用前置版本递增运算符++i
3.7:    cout<<*pbeg++< 3.8:    输出*pbeg所指的元素,然后pbeg指针向右诺一格
3.9:    等价于cout<<*pbeg< 3.10:    ++pbeg
3.11:    前者比后者简洁且更少出错
3.12:    ptr->mem (*ptr).men *iter.empty()
3.13:    ++*iter,iter++→empty()
3.14:    string s = "word"
3.15:    string p1 = s + s[s.size()-1] == 's'?"":"s"
3.16:    左移<<右移>>
3.17:    位求反~ 1置0 0置1
3.18:    与&或1
3.19:    异或^,异1,不同为1
3.20:    1UL<<27
3.21:    quiz1 |= 1UL<<27 || 010=010 1|0=1
3.22:    quiz1 &= ~(1UL<<27) || 1&0=0 0%1=0
3.23:    quiz1 |= 1UL<<27 第二十七位0或1 → 1,其它位0或1 → 不变
3.24:    quiz1 &= ~(1UL<<27)第二十七位0或1→0,其它位0或1 → 不变
3.25:    quiz1 &(1UL<<27)第二十七位0&1=0 1&1=0 其它位0&0=0 1&0=0
3.26:    ~'q'<<6的值
3.27:    sizeof取得的值是size_t类型
3.28:    size of expr返回的是表达式结果类型的大小
3.29:    sizeof并不实际计算其运算对象的值
3.30:    sizeof data;sizeof p;sizeof *p;sizeof data.revenue;sizeof Sales_data::revenus;sizeof *p,p为NULL也不会出错,因为NULL没有被解引用
3.31:    对string等对象执行sizeof运算只返回该类型固定部分的大小
3.32:    constexpr size_t = sizeof(ia)/sizeof(*ia)
3.33:    隐式转换
3.34:    尽量避免损失精度
3.35:    static_cast(j)大转小,通知编辑器不在乎精度损失
3.36:    const_cast(cp)
3.37:    reinterpret_cast改类型名字却不改本质,使用不当会存在很大的问题
3.38:    case true:{string s;}break;case false:;
3.39:    范围for语句 for(x:x)x;C++11;
3.40:    不能通过范围for语句添加,删除初始值列表的元素
3.41:    stdexcept runtime_error
3.42:    terminate标准库函数
3.43:    执行该函数导致程序非正常退出
3.44:    异常安全(exception safe)
3.45:    程序运行到一半以后中止,前面已计算好的对象的处理工作
3.46:    const char* 转化那位int
3.47:    函数参数拷贝的指针的值,拷贝之后,两个指针是不同的值
3.48:    实参类型相同,initializer_list lst
3.49:    无法改变initializer_list对象中元素的值
3.50:    实参数量未知时使用
3.51:    const string&manip()返回值作为局部变量会被释放,访问该引用会出现问题
3.52:    尾置返回类型
ENDP200 20151012 星期一


4.1:    返回类型void的话为隐性执行return
4.2:    返回局部对象的引用或实值的引用都是指向了不再可用的内存空间
4.3:    返回花括号包围的值的列表
4.4:    vector返回{"functionX","obey",expected.actual}
4.5:    根据excepted和actual是否相等来初始化
4.6:    main无return隐式插入return 0
4.7:    cstdlib头文件
4.8:    if(some_failure)return EXIT_FAILURE;else return EXIT_SUCCESS
4.9:    main函数不能调用它自己
4.10:    typedef int arrT[10]
4.11:    using arrT = int[10]
4.12:    arrT* func(int i)
4.13:    int (*pz)[10]=&arr
4.14:    int (*func(int i))[10]
4.15:    auto func(int i) → int(*)[10]
4.16:    int odd[] = {1,3,5,7,9}
4.17:    int even[] = {0,2,4,6,8}
4.18:    decltype(odd) *arrPtr(int i){return (i%2)?&add:&even}
4.19:    main函数不能重载
4.20:    typedef Phone Telno重载时是相同的
4.21:    Account &/*和const Account&/*是可以重载的
4.22:    非常量对象或指针优先选用非常量版本
4.23:    当它的实参不是变量时,返回一个普通的引用
4.24:    auto &r = shorterString(const_cast)(s1),const_cast(s2);
4.25:    先转成count,再去掉const返回
4.26:    在当前作用域找到了
4.27:    所需的名字,编译器会忽略外层的作用域下的同名实体
4.28:    typedef string::size_type sz
4.29:    string screen(s2 ht = 24 , sz wid = 80 , charbackgrnd = ' ')
4.30:    一旦某个实参被赋予了默认值,它后面的所有形参都必须有默认值
4.31:    对应的十六进制数是0x3F,十进制数的63
4.32:    内联-小,直接,频繁
4.33:    constexpr int new_sz()
4.34:    存在两种可能的算术类型转换则该调用具有二义性
4.35:    函数指针
4.36:    pf = 0
4.37:    void useBigger(const string&s1),const string&s2,bool,pf/(*pf)(const string&,const string&));
4.38:    typedef decltype(lengthCompare) Func2;
4.39:    using F=int(int*,int)
4.40:    using PF = (int*)(int*,int*)
4.41:    在类定义开始或结束前的位置集中声明友元
4.42:    避免在多处使用同样的代码
4.43:    两个类即使成员一样也是不同的类型
4.44:    explicit抑制构造函数的隐式转换
4.45:    只能使用直接初始化
4.46:    转换构造函数combine(cosnt Sales_data&)
4.47:    combine(string)
4.48:    combine(istream)
4.49:    Sales_data(const std::string&s)或(std::istream&)
4.50:    显式地强制进行转换 item_combine(Sales_data(null_book))
4.51:    item.combine(Sales_data(null_book))
4.52:    item_combine(static_cast(cin))
4.53:    聚合类可以用花括号来给其数据成员赋值
4.54:    constexpr函数的参数和返回值必须是字面值类型
4.55:    宽字符版对象wcin,wcout,wcerr
4.56:    istream→ifstream istringstream
4.57:    eof()
4.58:    eofbit置good有效状态,clear()状态位复位 rdstate()返回当前状态
4.59:    一个流一旦发生错误,其上后续的IO操作都会失败
4.60:    while(cin>>word);
4.61:    能输入成功则流保持有效状态
4.62:    auto old_stage = cin.rdstate()
4.63:    cin.clear()
4.64:    process_input(cin)
4.65:    cin.setState(old_stage)
4.66:    cout<<"hi!"< 4.67:    换行/无/空字符,刷新缓冲区
4.68:    cout< 4.69:    cout< 4.70:    所有输出操作后都会立即刷新缓冲区
4.71:    cout< 4.72:    fstream 读写给定文件
4.73:    fstream is_open()
4.74:    if(ofstream)
4.75:    in以读方式打开
4.76:    out以写方式打开
4.77:    app每次写操作前均定位到文件末尾
4.78:    ate打开文件后立即定位到文件末尾
4.79:    trunc截断文件,binary以二进制方式进行IO
4.80:    截断文件,文件的内容会被丢弃
4.81:    ofstream app("file2","ofstream","app")
4.82:    getline(cin,line)
4.83:    istringstream record(line)
4.84:    record>>info.name
4.85:    while(record>>word)
4.86:    按空格依次读取
4.87:    badNums<<" "< 4.88:    formatted<<' '< 4.89:    vector在尾部之外的位置插入或删除元素可能会很慢,deque双端队列,在头尾位置插入/删除速度很快
4.90:    list双向链表
4.91:    forward_list单向链表
4.92:    array固定大小数组,不能添加或删除元素
4.93:    空间的额外开销很重要
4.94:    不要使用list或forward_list
4.95:    顺序容器,关联容器和无序容器
4.96:    较旧的编译器需要在两个尖括号上输入空格
4.97:    iterator迭代器
4.98:    获取迭代器begin() end() cbegin() cend()
4.99:    返回const_iterator
4.100:    [begin,end)
4.101:    while(begin!=end)*begin=val;++begin;
4.102:    list::iterator _iter;
4.103:    auto it!=a.begin();
4.104:    带r的版本返回反向迭代器,以c开头的版本则返回const迭代器
4.105:    但不需要写访问时,应使用cbegin和cend
4.106:    (const vector).cbegin()
4.107:    list list2(authors)
4.108:    forward_list words(articles.begin(),articles.end());
4.109:    只有顺序容器的构造函数才接受大小参数,关联容器并不支持
ENDP308 20151019 星期一


5.1:    array
5.2:    c1 = c2 等于右边容器的原大小
5.3:    c1 = {a,b,c}的size变为3
5.4:    swap(c1,c2)
5.5:    list names.assign(vector.cbegin(),vector.cend());
5.6:    list slist1(1)
5.7:    vector(10)(24)
5.8:    swap(vector(10),(24))
5.9:    连值带大小一起交换,除了array以外其它容器的操作都会很快,只是交换了两个容器的内部数据结构
5.10:    数组首位和尾位两个指针,两个数组交换直接交换这两个指针
5.11:    swap只对array进行元素操作
5.12:    除string之外,指向容器的迭代器引用,指针在swap操作后都不会失效
5.13:    同一使用非成员版本swap是一个好习惯
5.14:    max_size返回一个大于等于该类型容器所能容纳的最大元素数的值
5.15:    forward_list支持max_size和empty,但不支持sizes
5.16:    每个容器都支持相等运算符、除了无需容器都支持关系运算符(>,>=,<,<=)
5.17:    <第一,顺序判断对应的两个值大小,若都相等则判断vector的大小
5.18:    如vector的泛型中的类没有大于小于号的运算符运算函数则错误
5.19:    顺序容器forward_list
5.20:    push_front(),push_back
5.21:    iter = list.insert(iter.word)
5.22:    insert返回插入单词的位置
5.23:    emplace front <-> push.front、emplace<->insert、push_back<->emplace_back
5.24:    emplace_back("978-0590353403",25,15.99)
5.25:    等价于push_back(Sales_data("978-0590353403",25,15.99));P308
5.26:    emplace_back会根据参数调用指定的构造函数
5.27:    deque双向队列 begin()返回迭代器的指针、front()返回首元素的引用
5.28:    auto val = *c.begin(),val2 = c.font()
5.29:    c.end()
5.30:    at和下标操作只适用于string,vector,deque和array
5.31:    back不适用与forward_list
5.32:    at抛出out_of_range异常,如果下标越界
5.33:    容量调用成员函数返回的都是引用
5.34:    auto&v = c.back(),v=1024改变c中元素
5.35:    auto v2 = c.back 未改变c中的元素
5.36:    快速随机访问的容器string vector deque array
5.37:    希望下标合法可以用at成员函数
5.38:    vector和string不支持push_front和pop_front
5.39:    forward_list不支持pop_back
5.40:    list.front()获取首元素,pop_front完成处理后删除首元素
5.41:    list lst={0,1,2,3,4,5,6,7,8,9}
5.42:    lst.erase(it)返回删除的元素之后的元素
5.43:    elem1 = slist.end()
5.44:    forward_list 单向链表
5.45:    insert→insert_after
5.46:    list.resize(n,t),调整大小为n,新添加的元素的指针、引用和迭代器:vector和string在存储空间重新分配时失效
5.47:    deque首位位置之外的任何位置插入都失效
5.48:    首尾位置就只有迭代器失效
5.49:    list和forward_list始终有效
5.50:    删除元素,list和forward_list有效
5.51:    deque首尾之外删除元素,指向被删除元素外其它元素的迭代器、引用或指针也会失效、尾元素尾后迭代器失效,删除首元素不影响
5.52:    vector,string被删元素之前元素有效
5.53:    删尾元素,尾后迭代器总是会失效
5.54:    调用erase后不必递增迭代器
5.55:    insert后需要递增迭代器两次
5.56:    不要保存end返回的迭代器,经常失效
5.57:    while(begin!=v.end())
5.58:    reserve(n)分配至少能容纳n个元素的内存空间
5.59:    shrink_to_fit只适用于vector,string和deque
5.60:    capacity和reserve只适用于vector和string
5.61:    resize改变元素的数目,reserve改变容器的容量
5.62:    size()已保存的元素数目,capacity不分配新的内存空间前提下它最多可以保存多少元素
5.63:    vector的实现采用的策略似乎是将当前容量翻倍
5.64:    shrink_to_fit()归还多余内存,但标准库并不保证退换内存
5.65:    string s(s2,pos2,len2)
5.66:    s.substr(0,s.size()-0)
5.67:    string类型支持顺序容器的赋值运算符以及assign,insert和erase操作
5.68:    s.insert(s.size(),5,'1')
5.69:    s.erase(s.size()-5,5)
5.70:    string find("...")返回第一个匹配位置的下标
5.71:    find大小写敏感
5.72:    find_first.of(numbers,pos)
5.73:    int i = 42
5.74:    string s = to_string(i)将整数i转换为字符表示形式
5.75:    double d = stod(s)
5.76:    将字符串s转换为浮点数 s to i l ul u ull f d ld
5.77:    顺序容器适配器:stack,queue,priority_queue
5.78:    stack stk(deque)
5.79:    stack适配器接受一个顺序容器
5.80:    stack和queue基于deque实现
5.81:    priority_queue在vector之上实现
5.82:    stack>,重载默认容器类型
5.83:    适配器要求容器具有添加,删除,访问尾元素的能力,所以forward_list不行
5.84:    stack使用除array和forward_list以外的容器类型构建
5.85:    queue←list和deque而不能用vector
5.86:    prioriry - queue允许为队列中的元素添加优先级,新加入的元素排在优先级比它低的元素之前
5.87:    algorithm头文件,numeric数值泛型算法
5.88:    find(vec.cbegin()),vec.cend().val
5.89:    string val = "a value"
5.90:    numeric → accumulate(vec.cbegin()),vec.cend(),0
5.91:    返回求和的值
5.92:    string sum = accumulate(v.cbegin(),v.cend(),string(""))
5.93:    第三个参数必须保证有+法运算
5.94:    cbegin(),cend()只读begin() end()改变
5.95:    equal(r1.cbegin(),r1.cend(),r2.cbegin())若都相等返回true,否则返回false
5.96:    equal算法假设第二个序列至少比第一个序列长
5.97:    fill(vec.begin(),vec.begin()+vec.size()/2,10)将其中一个子序列赋值为10
5.98:    fill_n(vec.begin(),n,val)将n位赋值为val
5.99:    iterator→back_inserted()
5.100:    auto it = back_inserter(vec)
5.101:    *it = 42
5.102:    fill_n(back_inserter(vec),10,0)
5.103:    auto ret = copy(begin(a1),end(a1),a2)
5.104:    将a1内容赋给a2,ret为a2尾元素之后的位置
5.105:    sort(words.begin(),words.end(),auto end_unique)=unique(words.begin(),words.end()),words.erase(end_unique,words.end())
5.106:    谓词,一元,二元;
5.107:    bool isShorted(..),sort(words.begin(),words.end(),isShorter)
5.108:    stable_sort(words.begin(),words.end(),isShorter)相同长度的元素按字典序排列
5.109:    lambda
5.110:    [capture list](parameter list)→return type{function body}
5.111:    auto f = [] { return 42; }
5.112:    cout< 5.113:    [](const string&a,const string&b){
5.114:     return a.size() 5.115:    }
5.116:    [sz](const string &a){
5.117:     return a.size()>=sz;
5.118:    }
5.119:    auto wc = find_if(words.begin(),words.end(),[sz](cosnt string&a){return a.size()>=sz;})
5.120:    如果不存在返回words.end(),[](const string&s){cout< 5.121:    不能拷贝ostream对象
5.122:    尽量保持lambda的变量捕获简单化
5.123:    [=](const string&s){return s.size()>=sz;}
5.124:    &采用捕获引用方式,=表示采用值捕获方式
5.125:    隐式捕获
5.126:    [&.identifier_list]值捕获?[=,identifier_list]引用捕获?
5.127:    [](int i){if(i<0)return -i;else return i;}
5.128:    推断返回void,却返回了int,编译错误
5.129:    尾置返回类型[](int i)→int{if...}
5.130:    find_if接受一元谓词(函数单一参数)
5.131:    functional → bind 解决传递一个长度参数的问题,解决一元谓词问题
5.132:    auto wc = find_if(words.begin(),words.end(),bind(check_suze,-1,sz))
5.133:    命名空间placeholders,本身定义在std中:using std::placeholders::_1
5.134:    using namespace std::placeholders
5.135:    bind(f,a,b,-2,c,-1)
5.136:    插入迭代器,流迭代器,反向迭代器,移动迭代器
5.137:    iostream迭代器
5.138:    ifstream in("afile"),istream_iterator str_it(in)//从"afile"读取字符串,头文件iterator istream_iterator in_iter(cin).eof
5.139:    while(in_iter!=eof)vec.push_back(*in_iter++)
5.140:    vector vec(in_iter.eof)
5.141:    copy(vec.begin(),vec.end(),ostream_iterator(cout," "))
5.142:    使用流迭代器处理类类型
5.143:     ┌   vec.cbegin() →    vec.cend()   ┐
5.144:    vec.crend() →   vec.crbegin() ←   ┘
5.145:    输入和输出前向双向随机访问迭代器
5.146:    *_if版本的算法接受一个谓词
5.147:    *_copy版本的算法要求能写到额外的空间
5.148:    splice成员将链表移动给另一个链表
5.149:    map word_count
5.150:    ++word_count[string]
5.151:    if(exclude.find(word) == exclude.end())
5.152:    multimap、multiset 一个特定的单词可具有多个与之关联的词义
5.153:    utility → pair
5.154:    pair的数据成员是public的
END 20151026 星期一


6.1:    无序关联容器
6.2:    无序容器 解决→ 维护元素的序代价非常昂贵
6.3:    管理桶
6.4:    关联数组 associative array 通过关键字而非下标搜索元素
6.5:    关联容器 associative container保存对象的集合,通过关键字高效查找
6.6:    哈希函数 size_t
6.7:    key_type关联容器定义的类型,保存和提取值的关键字的类型
6.8:    map关联数组。类似vector。解引用一个map迭代器会生成一个pair,它保存一个const关键字及其关联的值
6.9:    mapped_type映射类型定义的类型,就是映射中关键字关联的值的类型
6.10:    multimap关联容器类型,类似map,一个给定的关键字可以出现多次,不支持下标操作
6.11:    multiset保存关键字的关联容器类型,给定关键字可出现多次
6.12:    pair类型,保存名为first和second的public数据成员。pair类型是模板类型,接受两个类型参数作为其成员的类型
6.13:    set保存关键字的关联容器。在一个set中,一个给定的关键字只能出现一次
6.14:    严格弱势,比较任意两个值并确定哪个更小
6.15:    无序容器,用哈希技术存储访问元素
6.16:    []用于map和unordered_map,非const对象
6.17:    静态内存(局部,类static,函数外的变量)
6.18:    栈内存(函数内非static对象)
6.19:    由编译器自动创建和销毁
6.20:    内存池→自由空间或堆、用于动态分配的对象(程序运行时分配的对象,由程序来控制)
6.21:    两种智能指针(smark pointer)
6.22:    负责自动释放所指向的对象
6.23:    shared_ptr允许多个指针指向同一个对象
6.24:    unique_ptr“独占”所指向的对象
6.25:    标准库还定义了一个名为weak_ptr的伴随类
6.26:    shared_ptr类似vector
6.27:    shared_ptr p1
6.28:    shared_ptr> p2
6.29:    if(p1&&p1->empty())
ENDP400 20151027 星期二


7.1:    静态内存(局部static对象,类static数据成员,定义在任何函数之外的变量)
7.2:    栈内存(函数内的非static对象)
7.3:    前面两种由编译器自动创建和销毁
7.4:    栈对象仅在定义的程序块运行时才存在
7.5:    内存池(自由空间或堆)→动态分配的对象
7.6:    shared_ptr多个指针指向同一个对象,unique_ptr独占作指向的对象,weak_ptr弱引用,指向shared_ptr,memory.h
7.7:    shared_ptr unique_ptr p
7.8:    *p->mem p.get() make_shared(args) shared_ptr p(g)
7.9:    智能指针为了避免用户忘了释放指针内存
7.10:    make_shared (42)
END 20151102 星期一


8.1:    p=q 递减p的引用计数,递增q的引用计数
8.2:    p=q 操作相当于p、q => q、q
8.3:    shared_ptr若被销毁,指向内存的引用计数减1,若引用计数为0,内存空间被释放
8.4:    程序需要在多个对象间共享数据
8.5:    v1 = v2,如何令v1和v2共享相同的元素而不是拷贝一份元素
8.6:    check(size_type i,const string& msg) if(i>=data->size())throw out_of_range(msg);
8.7:    new int(分配失败,new抛出std::bad_alloc);
8.8:    new (nothrow) int分配失败,new返回一个空指针
8.9:    delete执行两个动作:销毁给定指针所指向的对象,释放对应的内存
8.10:    释放一个空指针总是没有错误的
8.11:    空悬指针 dangling pointer
8.12:    在指针离开作用域之前释放掉指针
8.13:    若要保留指针,释放内存后将nullptr赋值给指针
8.14:    在实际系统中,查找指向相同内存的所有指针是异常困难的
8.15:    shared_ptr和new结合使用
8.16:    shared_ptr pz(new int(42))
8.17:    接受指针参数的智能指针构造函数是explicit
8.18:    抑制构造函数定义的隐式转换
8.19:    void process(shared_ptr ptr)
8.20:    shared_ptr.get()返回一个内置指针*p,如果delete p则原来的智能指针也无法使用,delete p也可以是{shared_ptr(q);}
8.21:    永远不要使用get初始化另一个智能指针或者为另一个智能指针赋值
8.22:    if(!p.unique())p.reset(new string(*p))
8.23:    指向该对象的智能指针超过1个,重设其中一个只能指针的指向空间不会造成原内存空间的释放
8.24:    若某类没有析构函数,可以用shared_ptr保证该类被正确关闭
8.25:    释放操作由我们自己定义函数来定义shared_ptrp(&c,end_connection)
8.26:    不使用相同的内置指针值初始化(或reset)多个智能指针
8.27:    不delete get()返回的指针
8.28:    不使用get()初始化或reset另一个智能指针
8.29:    如果你使用get()返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了
8.30:    如果使用智能指针管理的资源不是new分配的内存,记住传递给它一个删除器
8.31:    只有一个unique_ptr指向一个内存空间
8.32:    unique_ptr不支持赋值unique_ptr p2(p1.release())
8.33:    p2.reset(p3.release())
8.34:    传递unique_ptr参数和返回unique_ptr
8.35:    由于编译器知道unique_ptr要被销毁
8.36:    auto_ptr
8.37:    weak_ptr→shared_ptr
8.38:    大多数应用应该使用标准库容器而不是动态分配的数组
8.39:    allocator alloc;
8.40:    auto const p = alloc.allocate(p)
8.41:    alloc.construct(q++)
8.42:    alloc.destroy(--q)
8.43:    TextQuery
8.44:    拷贝构造、赋值、移动构造、赋值、析构
8.45:    拷贝控制操作
8.46:    合成拷贝构造函数
8.47:    拷贝构造函数的第一个参数必须是一个引用类型Foo(const Foo&)
8.48:    拷贝构造函数通常不应该是explicit
8.49:    一个类一定会有一个拷贝构造函数
8.50:    string s(args)//直接初始化
8.51:    string s2 = args;//拷贝初始化
8.52:    拷贝赋值运算符trans = accum
8.53:    析构函数自身并不直接销毁成员,而是在函数体之后自动销毁
8.54:    在类内对合成版本的成员函数使用 = default,内联,在类外使用 = defaykt,不是内联 P449
8.55:    在函数的参数列表后加上=delete,声明但不能使用
8.56:    =delete通知编译器我们不希望定义这些成员
8.57:    析构函数不能是删除的成员
8.58:    拷贝控制和资源管理
8.59:    P456实战
8.60:    void swap(lhs.h,rhs.h)
8.61:    拷贝控制实例Folder和Message
8.62:    P456 ~ P470实践项目
8.63:    右值引用&&
8.64:    int i = 42
8.65:    int& r = i
8.66:    const int &r3 = i * 42
8.67:    int&& rr2 = i*42
8.68:    左值和右值 P471
8.69:    int&& rr3 = std::move(rr1)
8.70:    移动拷贝和移动赋值
8.71:    "窃取"资源而不是"拷贝"资源
8.72:    在赋值以后将指针为nullptr
8.73:    noexcept承诺一个函数不抛出异常的一种方法
8.74:    strVec(strVec&&)noexcept
8.75:    移后源对象必须可析构
8.76:    合成的移动操作
8.77:    移动右值,拷贝左值
8.78:    如果没有移动构造函数,右值也被拷贝
8.79:    拷贝并交换赋值运算符和移动操作
8.80:    移动迭代器
8.81:    auto on=(s1+s2) find('a')在一个string右值上调用find成员,s1+s2="wow"
8.82:    对两个string的连接结果——一个右值,进行了赋值
8.83:    int i,j;i和j是左值
8.84:    Foo& retFoo()返回一个左值
8.85:    Foo recVal()返回一个右值
8.86:    Foo anotherMem()const&引用限定符
8.87:    using Comp = bool(const int &,const int &)
8.88:    Foo sorted(Comp*)
8.89:    Foo sorted(Comp*)const
8.90:    cout< 8.91:    只能重载已有的运算符,无权发明新的运算符号
8.92:    x == y+z    x ==(y+z)
8.93:    data1 + data2 等价于 operator+(data1,data2)
8.94:    有operator==通常也应该有operator!=
8.95:    输出运算符<<,输入运算符>>,算术和关系逻辑运算符+-*/
8.96:    相等运算符== 关系运算符>< 赋值运算符=  复合赋值运算符+=
ENDP500    20151103星期二


9.1:    string& operator[](std::size_t n){return elements[n];}
9.2:    &operator++()/--()
9.3:    operator++(int)/--(int)
9.4:    p.operator++(0)
9.5:    p.operator()
9.6:    *operator → ()const{return &this->operator*()};
9.7:    struct absInt{int operator()(int val)const{return val<0?-val:val;}}
9.8:    int i = -42;absInt absObj;int ui=absObj(i);
9.9:    函数调用运算符
9.10:    for_each(vs.begin(),vs.end(),PrintString(cerr,'\n'));
9.11:    function接受两个int、返回一个int的可调用对象
9.12:    functionf2 = divide()
9.13:    不能直接将重载函数的名字存于function类型的对象中
9.14:    解决二义性的方法:存储函数指针
9.15:    lambda
9.16:    类型转换运算符operator() type()const
9.17:    定义自bool的类型转换还是比较普通的现象
9.18:    二义性与转换目标为内置类型的多重类型转换
9.19:    如果Foo类有一个几首Bar类对象的构造函数,则不要再Bar类中再定义转换目标是Foo类的类型转换运算符
9.20:    manip(const C&) manip(const D&)manip(C(10))  OOP
9.21:    继承inheritance 基类  派生类
9.22:    要求派生类有自己的函数版本,声明成虚函数
9.23:    在该函数的形参列表之后增加一个override关键字
9.24:    运行时绑定
9.25:    protected派生类有权访问该成员,而禁止其它用户访问
9.26:    类派生列表,哪个基类继承下来
9.27:    派生类的对象不能直接初始化基类的成员
9.28:    派生类的声明不包含:public
9.29:    class NoDervier final{}防止继承发生
9.30:    静态类型 动态类型
9.31:    不存在从基类向派生类的隐式类型转换
9.32:    派生类向基类的自动类型转换只对指针或引用类型有效
9.33:    类的虚函数返回类型是类本身的指针或引用时
9.34:    形参列表不同、派生类的函数并没有覆盖掉基类中的版本
9.35:    书写=0就可以将一个虚函数说明为纯虚函数
9.36:    纯虚函数的类是抽象基类
9.37:    重构refactoring
9.38:    private继承 所有成员都变私有了,接下来无法直接继承
9.39:    protected继承,(除了private)所有成员都受保护了
9.40:    public继承 原先的成员类型不变
9.41:    D继承自B,D公有地继承B,用户代码才能使用派生类向基类的转换
9.42:    Quote item Bulk_quote bulkQuote *p = &item
9.43:    p = &bulk Quote &r = bulk
9.44:    成员函数和友元都能使用派转基类,无论继承方式
9.45:    友元不能被继承
9.46:    改变继承类继承的某个名字的访问级别用using声明
9.47:    私有继承后,若有些成员仍想继续继承,用using 基类::成员名字,放在public或protected下即可
9.48:    struct默认public继承,class默认private继承
9.49:    继承——派生类的作用域嵌套在其基类的作用域之内
9.50:    名字冲突与继承——内层作用域名字隐藏外层作用域的名字
9.51:    派生类最好不要重用基类的名字
9.52:    派生类最好不要重用基类的名字
9.53:    如果基类派生类有同名不同形参的函数,派生类在不同作用域运算符的情况下不能调用基类的同名函数
9.54:    虚析构函数,基类指针有可能指向派生类,此时应调用派生类析构函数而非基类
9.55:    合成拷贝控制与继承
9.56:    基类派生类的构造函数都调用一遍
9.57:    移动操作std::move(T)
9.58:    在构造函数和析构函数中调用虚函数
9.59:    不能把具有继承关系的多种类型的对象直接存放在容器中,最好的容器类型是基类指针
9.60:    文本查询程序再探
9.61:    抽象基类
9.62:    Query q = Query("fiery")& Query("bird")|Query("wind")函数模板,泛型
9.63:    template
9.64:    大多数编译错误在实例化期间报告
9.65:    实例化类模板
9.66:    Blob::Blob(std::initializer_list){};P618
9.67:    BlobPtr& operator++/--()等价于BlobPtr& operator++/--(),template默认为int
9.68:    类模板的成员模板
9.69:    显示实例化extern template declaration
9.70:    extern模板声明不会在本文件中生成实例化代码
9.71:    template
9.72:    templateusing twin = pair
9.73:    Foo::static
ENDP600 20151109星期一


10.1:    模板的实例
10.2:    非类型参数 template
10.3:    模板编译 auto fcn(It beg,It end)->decltype(*beg){return *beg;} int (*pf1)const int&,const int&) = compare
10.4:    右值引用T&& ← 42,左值引用T&←i
10.5:    引用折叠x&&,x& &&和x&& &都折叠成类型x&,类型x&& &&折叠成x&&
10.6:    右值引用只用于两种情况,实参转发和模板重载
10.7:    templatevoid f(T&&)
10.8:    templatevoid f(const T&)
10.9:    std::move
10.10:    使用右值引用模板
10.11:    既可以传递给move一个左值,也可以传递给它一个右值 
10.12:    s2 = std::move(string("byte!"))或std::move(s1)
10.13:    前一个正确,从右值移动数据
10.14:    后一个也正确,但赋值以后s1的值不确定
10.15:    用static_cast显式地将一个左值转换为一个右值引用
10.16:    转发、用一个函数直接调用另一个函数,此时引用不会影响原变量的值
10.17:    i,j,&是左值,&&,i*42,42是右值
10.18:    T&&做函数参数可以保持实参的左右值属性
10.19:    utility h->forward
10.20:    void f(int vi,int&v2)
10.21:    void flip2(F f,T1&&t1,T2&&t2)
10.22:    debug_rep(const T& t)(T*p)
10.23:    ostringstream
10.24:    可变参数模板,参数包,模板参数包,函数参数包
10.25:    template
10.26:    void foo(const T& t,const Args&...rest) P619
10.27:    namespace primer:cplusplus_primer
10.28:    Qlib = cplusplus_primer::QueryLib
10.29:    头文件最多只能在它的函数或命名空间内使用using指示或using声明
10.30:    using声明——简单地令名字在局部作用域内有效
10.31:    using指示——令整个命名空间的所有内容变得有效
10.32:    给函数传递一个类类型的对象,在常规的作用域和实参类所属的命名空间查找 虚继承
10.33:    与基类共享资源
10.34:    public virtual ToyAnimal;
10.35:    void* operator new(size_t)
10.36:    operator new[]
10.37:    void* operator new(size_t,void*)
10.38:    只供标准库使用,用户不能自定义
10.39:    cstdlib->malloc、free
10.40:    typeid返回表达式的类型dynamic_cast将基类指针或引用安全地转换为派生类的指针或引用
10.41:    dynamic_cast(e)
10.42:    为具有继承关系的类实现相等运算符可以使用RTTI解决问题
10.43:    ① 相等运算符的形参是基类的引用 ② 使用typeid检查两个运算对象的类型是否一致 不一致返回false,一致调用equalP734
10.44:    typeinfo.h->typeinfo
10.45:    typeid()返回typeinfo
10.46:    enum枚举值默认从0开始,依次加1
10.47:    enum intValues:unsigbed long long{}
10.48:    默认int
10.49:    functionfcn = &string::empty mem_fn推断成员的类型
10.50:    bind以成员函数生成一个可调用的对象
10.51:    嵌套类或嵌套类型
10.52:    只在类中可见
10.53:    union节省空间的类,有多个数据成员,只有一个有值
10.54:    union Token{}
10.55:    匿名union union{}
10.56:    仅在所在作用域可用
10.57:    union想要构造或销毁类类型的成员必须执行非常复杂的工作
10.58:    位域bit
10.59:    bit mode:2
10.60:    mode占2位二进制位
10.61:    指针无法指向位域
10.62:    volatile告诉编译器不应对这样的对象进行优化
10.63:    异常处理
10.64:    exception handling
10.65:    try,throw异常后如果没有找到catch语句,则在try外层的try块中找catch语句,如果有的话
10.66:    如果还是没有,推出函数,在函数外找
10.67:    栈展开stack unwinding
10.68:    找不到catch则调用标准库函数terminate
10.69:    栈展开的过程中对象被自动销毁
10.70:    析构函数抛出异常程序终止
10.71:    如果catch的参数类型是非引用类型,则该常数是异常对象中的一个副本
10.72:    异常与每个继承体系有关,则catch参数定位引用类型
10.73:    最终找到的catch未必是异常的最佳匹配
10.74:    越是专门的catch越应该置于整个catch列表的顶端
10.75:    把继承链底端类放在前面,顶端放后面
10.76:    在catch调用throw向上传递异常
10.77:    在catch以外的地方调用[throw;]直接调用terminate
10.78:    catch(...)捕获所有异常
10.79:    catch自上往下匹配
10.80:    handle_out_of_memory(e)
10.81:    void recoup(int) noexcept 不会抛出异常
10.82:    noexcept用在两种情况下:一是确定函数不会抛出异常 二是我们根本不知道如何处理异常
10.83:    noexcept(recoup(i))不抛出异常结果为true,否则结果为false
10.84:    noexcept异常说明符和运算符
10.85:    void f()noexcept(noexcept(g()))g承诺不会抛出异常,f也不会抛出异常
10.86:    函数指针和函数需要有一致的异常说明
10.87:    exception[bad_cast,bad_alloc,runtime_error[oveflow_error,underflow_error,range_error],logic_error[domain_error,invalid_argument,out_of_range,length_error]]
10.88:    exception<-拷贝[构造、赋值]、虚析构、what的虚成员、返回一个const char*
10.89:    namespace 将全局命名空间分割
10.90:    namespace不能定义在函数或类的内部
10.91:    命名空间作用域后无需分号
10.92:    把#include放在命名空间内部,使该头文件下所有名字变成该命名空间的成员
10.93:    template<> inline namespace外层命名空间可直接访问
10.94:    未命名的内存空间
10.95:    templatevoid g(Args...args){
10.96:     cout< 10.97:     cout< 10.98:    }
10.99:    template ostream& print(ostream&os,const T&t,const Args&..rest){
10.100:     os< 10.101:     return print(os,rest...);
10.102:    }
10.103:    非可变参数模板比可变参数模板更特例化,因此编译器选择非可变参数版本
10.104:    包扩展 模式 模板特例化、用在无法将一个指针转换为一个数组引用的时候
10.105:    类模板特例化、在类模板是特定类时,需要有不一样的成员
10.106:    template<>
10.107:    tuple类型,一个“快速而随意”的数据结构
10.108:    get<0>(item)
10.109:    确定一个对象的类型最简单的方法就是使用decltype
10.110:    bitset.h->bitset
10.111:    regex.h->正则表达式
10.112:    string pattern("[^c]ei");
10.113:    pattern="[[:alpha:]]*" + pattern + "[[:alpha:]]*";
10.114:    regex(pattern);
10.115:    smatch results;
10.116:    string test_str;
10.117:    if(regex_search(test_str,results.r))cout...;
10.118:    随机数 default_random_engine e1(time(0));
10.119:    uniform_real_distribution u(0,1)
10.120:    normal_distribution<> n(4,1.5) 均值,标准差
10.121:    lround(n(e));
10.122:    bernoulli_distribution 0.5的概率返回true
10.123:    boolalpha改变true和false的打印方式
10.124:    noboolalpha取消
10.125:    get_status()
10.126:    hex、oct、dec
10.127:    前导0x表示十六进制,前导0表示八进制
10.128:    cout.precision(12)
10.129:    cin.get cin.put
10.130:    gcount
10.131:    g版本读取数据,p版本写入数据
10.132:    seek.tell
ENDP683 20151110星期二


11.1:    调用其它语言编写的函数,链接指示
11.2:    导出C++函数到其他语言
ENDP762 20151116星期一


你可能感兴趣的:(C语言,C++primer,笔记)