左值:可以取地址的、有名字的,例如普通定义变量、变量的引用,指针。
右值:不可取地址的或者没有名字的,例如常量、表达式(a+b)、函数返回值func()。
顾名思义,对右值的引用,c++11使用,可以用于给寿命短暂的右值进行续命。
注意,右值引用本身是左值,是可以取地址的。
上面的代码中,A的构造函数实际上被执行了两次,第一次在GetA()里,第二次是在A a=GetA()处。
如果使用右值引用,则只构造函数只执行一次,减少临时变量构造函数的执行次数。
匿名函数,在需要传入函数的地方使用,非常方便,例如sort函数。
抽象数据类型,减少因为类型而重复定义的函数。
不能,因为模板函数在用户调用时才能确定实例化成哪一种类型,而定义在cpp文件中的模板函数实际上是空的,link时是无法找到实例化函数的。 定义在头文件中时,头文件会随着用户代码一起编译,此时便能生成具体的函数。
频繁地动态分配内存,尽量静态分配好内存。
对象的实例内存上其实地址存放一个指针,指向虚函数表,不同类型的对象虚函数表不一样。
基类数量+子类数量,假设基类A派生出B和C,那么一共有3张虚函数表。
子类的析构函数要设置为虚函数,这样,父类指针指向子类对象并且析构时,才会先执行子类的析构函数,后执行父类的析构函数。
否则,程序只会执行父类的析构函数,造成子类的内存泄漏等问题。
map基于红黑树实现。
unordered_map基于hashmap实现。
数组,每一个数组存放一个值,同时数组也是链表的表头,链表存放哈希键值冲突的元素。 如果链表过长,则转换成红黑树。
要注意共享变量的互斥,即不能同时又读又写,或者同时写。
在临界区域等待其他的锁。
避免方法:消费者不要在临界区域等待其他的锁,如果是小变量,临界区可以直接执行拷贝操作,如果是大内存,则拷贝指针。 不要把等待各个数据这种行为放到临界区域。
shared_ptr,普通的智能指针,
unique_ptr,只允许有一个引用者的智能指针
weak_ptr,能否防止循环引用的智能指针。
static类型的引用计数,指针本身,外加锁。
进程内的量,共享一个内存空间,切换开销大,操作系统资源分配基本单位。
线程属于进程,多个线程共享一个堆和方法区,每个线程有自己的栈,程序计数器,切换开销小,处理器调度和执行的基本单位。