C++高级编程(第3版)
- p163 RVO下返回const std::string&与string的区别?
- p196 ~T()中调用virtual函数式,执行基本的实现,而不是派生类的重载版本
- 子类virtual中调用基类的版本,使用作用域限定语法:Base::f()
- p198 upcast时应使用&或*类型,而不是value类型(导致截断)
- Note:多继承情况下兄弟子类之间的类型转换...(dynamic_cast只能用于基类/子类之间的转换!)
- p203 std::numeric_limits<double>::quiet_NaN()
- p208 多继承
- using Dog::eat(); //显式指定使用哪个基类重载版本(或称显式继承基类的virtual实现版本)
- C++不允许同一个基类被继承多次,但是允许菱形继承(why?最顶层的基类需要是抽象类)
- p215 当使用多个using继承多个基类的构造函数时,可能需要显式声明冲突的构造函数
- p226 子类只有一个vtable,其项可以指向基类的方法实现?
- p228 RTTI的typeid:唯一的作用是用于调试log输出
- p229 虚基类: class Dog : public virtual Animal { ... //还有一个“虚继承”没讲?不对,虚基类就是虚继承
- p219 派生类无法调用基类的private方法,并并意味着无法重写这些(virtual)方法
- p238 右值引用及移动语义(临时对象,浅表body及所有权转移)
- p246 constexpr函数
- p249 不同源文件中的非局部变量的初始化顺序是不确定的
- p257 C++ 11: 统一初始化 ClassA a = { ... };
- p259 初始化列表:initializer_list<int> 元素必须是同一类型
- p260 特性
- C++ 11:[\[noreturn]] [\[carries_dependency]]
- C++ 14:[\[deprecated]]
- p262 用户自定义字面量:raw/cooked
- 生模式:std::complex<double> operator "" _i(const char* p);熟模式使用(const char* s, size_t len)作为参数
- C++ 14:"Hello"s 及h,min,s,ms,us,ns用于std::chrono::duration
- p280 方法模板
- 对赋值和拷贝构造很有用?
- 不能用于virtual和dtor
- p287 模板继承 vs 模板特例化
- p288 替补函数语法
- C++ 11:auto f(T1 t1, T2 t2) -> dectype(t1+t2) { return t1+t2; } //这种写法实在很别扭
- C++ 14:直接用auto声明返回值类型
- p319 throw; //rethrow; 为什么重新抛出异常不需要任何参数?证明异常是C++运行时机制?
- p336 vs std::throw_with_nested(MyException("error!"));
- p341 new handler(略)
- p343 构造函数对function-try-blocks(这个知识点有点生僻)
- p371 C++ 11:可以将operator T()标记为explicit
- p372 智能指针类定义 operator *() 以使得可执行 if (!p) 或 if (p==nullptr)比较
- p414 V.emplace_back(12, "A"); //相当于V.push_back({12, "A"}); 在容器V对内部位置就地构造对象
- STL算法
- p458 find()如果没有找到特定元素,返回的是调用参数指定的尾部迭代器,而不是容器的
- p460 auto it = find_if(cbegin(Vec), endIt, [](int i){return i>100});
- p462 lambda
- mutable修饰:使得按值捕获可以修改变量(相当于左值了),但为什么不用按引用捕获呢?
- C++ 14:参数无需指定类型,可以由编译器自动推断:[](auto i){return i>100}
- C++ 14:允许捕捉表达式
- lambda作为参数,形参:const function<bool(int)>& callback
- p468 算术函数对象(模板化的运算符封装):plus、minus、multiplis、divides、modulus
- ?C++ 14支持“透明运算符仿函数”:multiplis<>()
- 比较函数对象:equal_to、not_equal_to、less、greater、less_equal、greater_equal
- 例:priority_queue<int, vector<int>, greater<>> myQueue;
- 函数对象适配器
- bind
- placeholders:_1 _2
- ref:传递引用参数
- 显式指定重载函数的版本:auto f = bind((void(*)(float))overloaded, _1);
- mem_fn(不如使用lambda)
- bind
- p479 C++ 14添加了equal()和missmatch()的一个新版本...
- p482 copy()只能改写目标容器中的元素,不能插入:copy(cbegin(v1), cend(v1), begin(v2));
- 变体:copy_backward copy_if copy_n partition_copy
- remove-erase习俗:根据谓词将源容器集合分成保留和删除的,然后调用容器的erase方法
- auto it = remove_if(begin(vec), end(vec), pred); ==> vec.erase(it, end(vec));
- unique是特殊的remove(O, really?那怎么用remove来实现unique?)
- for_each
- p458 find()如果没有找到特定元素,返回的是调用参数指定的尾部迭代器,而不是容器的
- p499 字符串前缀/字符类型:u8/UTF8的char、u/char16_t、U/char32_t、L/wchar_t
- p501 wcout.imbue(locale("C"); //类似于en_US,但数字输出不带任何标点符号
- regex库
- 基本模板类型:basic_regex、match_results、sub_match
- 3个关键算法:regex_{match, search, replace} //search只用于寻找第一个匹配?
- 迭代器:regex_iterator regex_token_iterator(获取匹配的所有实例)
- p520 std::function的模板参数:RetType(ArgTypes...)
- p530 随机数引擎模板
- random_device
- linear_congruential_engine
- mersenne_twister_engine
- subtract_with_carry_engine
- p535 分布
- ... auto gen = bind(dist, engine);
- p551 自定义STL扩展:hash_map(略)
- p586 模板参数模板(定义模板类型参数之间的约束关系)
- p588 非类型模板参数不能是对象,只能是int/枚举/指针/引用
- p590 部分特化
- class A<T*> ...
- p592 函数模板不允许部分特化,只能重载
- 模板递归*
- p600 可变参数模板
- template<typename... Types> class MyVariadicTemplClass {};
- void f(T1 a1, Tn... args){ ... f(args...); } //这种语法让人想起了Scheme语言里的卫生宏。。。
- 为了在使用非const引用时也能使用字面量,使用rvalue引用 + std::forward完美转发 改写:
- void f(T1&& a1, Tn&&... args) { ... f(std::forward(Tn>(args)...); } //Fuck!
- p603 元编程
- p607 trait(略)
- p618 C++中不要使用realloc!(但是JIT引擎经常需要手工控制class的内存布局?)
- 多线程:略