参考文献(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.17: vector
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.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.9: 等价于cout<<*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
3.36: const_cast
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
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
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
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
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.68: cout<
4.71: cout<
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.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
4.103: auto it!=a.begin();
4.104: 带r的版本返回反向迭代器,以c开头的版本则返回const迭代器
4.105: 但不需要写访问时,应使用cbegin和cend
4.106: (const vector
4.107: list
4.108: forward_list
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
5.6: list
5.7: vector
5.8: swap(vector
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
5.42: lst.erase(it)返回删除的元素之后的元素
5.43: elem1 = slist.end()
5.44: forward_list 单向链表
5.45: insert→insert_after
5.46: list
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
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.114: return a.size()
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
5.139: while(in_iter!=eof)vec.push_back(*in_iter++)
5.140: vector
5.141: copy(vec.begin(),vec.end(),ostream_iterator
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
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
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
7.8: *p->mem p.get() make_shared
7.9: 智能指针为了避免用户忘了释放指针内存
7.10: make_shared
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
8.17: 接受指针参数的智能指针构造函数是explicit
8.18: 抑制构造函数定义的隐式转换
8.19: void process(shared_ptr
8.20: shared_ptr
8.21: 永远不要使用get初始化另一个智能指针或者为另一个智能指针赋值
8.22: if(!p.unique())p.reset(new string(*p))
8.23: 指向该对象的智能指针超过1个,重设其中一个只能指针的指向空间不会造成原内存空间的释放
8.24: 若某类没有析构函数,可以用shared_ptr保证该类被正确关闭
8.25: 释放操作由我们自己定义函数来定义shared_ptr
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
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
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.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
9.12: function
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
9.67: BlobPtr& operator++/--()等价于BlobPtr
9.68: 类模板的成员模板
9.69: 显示实例化extern template declaration
9.70: extern模板声明不会在本文件中生成实例化代码
9.71: template
9.72: template
9.73: Foo
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: template
10.8: template
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
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: function
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: template
10.96: cout<
10.99: template
10.100: os<
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
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星期一