C++ 复习拾遗
C++复习拾遗
delceartype(f(x))返回调用f(x)的返回结果的类型
头文件不包含using声明
结构体或者类定义时,}后面一定不要忘了;
string.size()返回的是string::size_type类型而非int,与机器实现有关。可用auto or delceartype获取相关类型
string s = "Hello"+"World"是错误写法,因为*char无法相加
内置下标运算要求索引不一定是无符号,可以是负数
强制类型转换:cast-name
const_cast 强制去const标签(casts away the const)
reinterpret_cast:强制指针转类型
分离式编译: -c 参数表示生成对象文件(win:.obj UNIX:.o)
void fun(int a[10]);//表示我们期望传进来的数组有10个元素,但实际上不一定,因为数组是当做指针处理的
initializer_list处理类型相同的参数//可变参数
可以列表初始化返回值:return {"A","B"};
assert 关键字如果遇上NDEBUG宏被定义了,那么assert将不发挥作用
指向函数的指针
指向重载函数指正必须在上下文清晰地定义选用了哪个函数eg:int *p(int,int,double)
using A=B语法
decltype()简化返回的函数指针
从C++11开始,xx=default表示按照默认方式初始化类
class定义类默认private权限,而struct默认public权限
在类的开始或者结束前声明友元
mutable 修饰的类成员即使是const的变量中也可以被修改
const成员函数返回的引用也是const类型
友元函数在类里被声明之后不算是被声明,必须在定义域中再次声明
当类存在仅一个参数的构造方法时,可以隐式地将该参数的对象转化为此类的实例,用explicit关键字防止这种转化\
静态成员不能在类的内部初始化,但是可以 使用constexpr
静态成员可以是不完全类型,但是普通成员不行,且静态成员可以是默认实参
IO
当一个输入流被绑定到一个输出流时,任何读入操作都会引起刷新
lambda: [capture list](parameter list)-> return type{body}
& = 表示值捕获或者引用捕获
lambda 混合捕获
functional 库中bind 函数的用法
ref 和ref函数使对象变成引用
iostream迭代器
递增递减迭代器:递减迭代器iter++表示往前移
set支持有序遍历
动态内存
new (nothrow) type 若在内存不够时,返回空指针
make_shared函数最安全地使用动态指针
不要用shared_ptr.get()作为参数初始化一个智能指针
shared_ptr支持自定义删除器
unique_ptr.release()放弃对指针控制权,并将自己置空
allocate类
allocate必须使用construct构造对象
类设计者工具
拷贝函数:第一个参数为自身引用,而且其他任何额外参数都有默认值
函数声明后面跟 = delete使之成为删除的函数, 如拷贝函数后面更=delete阻止拷贝
析构函数不可是被删除的成员
右值引用(水过)
右值(read value rvalue可读值)
左值(locator value可寻址值)
只能对即将销毁的值使用右值引用,(&&valuable)表示一个右值引用
std::move()将一个左值转化为一个右值
noexcept表示不抛出任何异常
运算符重载
a+b 等价于 operator+(a,b)
输入输出运算符重载
ostream &operator<<(ostream &os,...)
->运算符重载
()运算符重载
function
类型转换
类型转换符operator type() const;
override 表示重载
final表示阻止覆盖
使用p->SuperClass::function()避免虚函数机制
声明后加=0 表示是一个纯虚函数
面向对象
私有继承即把基类的所有对象统统变成私有
using 改变成员访问级别
class默认私有继承
struct 默认公邮继承
using 类名 直接使用基类的构造函数等价于derived(params):base(args)}{}(多重继承的时候如果超类都有相同参数列表的构造且均被使用,则报错)
不能在一个容器中放若干具有继承关系的不同类的对象,对应的处理方法是使用智能指针
编译器认为具有多个父类的子类向任意父类类型转换都是一样好的,这样可能引发错误。P714
虚继承
模板与泛型
非类型模板参数
inline constexpr 说明符在template后面
默认模板实参
多个地方使用同样模板的情况下,加个extern词头,可以减少实例化对象,减少开销
泛型模板可变参数typename.... args(args是参数包)
sizeof...()返回参数个数
args...表示包扩展,拓展后表示一个或多个逗号分隔的参数(P621)
f(args)...,将包拓展后,并将每各项作为参数分别调用f
转发参数包利用forward
异常
重新抛出:throw;
try语句块ClassName(args)try:A(a){}catch(exception){}
fun()noexcept == fun()throw()
noexcept运算符
未命名的命名空间:
直接使用成员名字
只在单个文件内起作用
枚举
enum:Name:typename 指定枚举成员类型,不指定就默认int
成员指针
成员指针不是可调用对象,find_if(beg,end,&string::empty())是不行的
成员指针
function生成可调用对象
mem_fn也可以生成可调用对象
bind生成可调用对象
union
任何时刻只能有一个成员有值
匿名union
用类管理union
局部类
局部类不能使用函数中定义的变量
位域
unsigned type name: bit count
& 指针不能用于位域
violate
violate关键字告诉编译器不应该优化此变量,它的值由外界改变