1、指针指针
auto_ptr:剥夺所有权机制,C++11已废弃,使用不安全
unique_ptr:针对auto_ptr的改进
share_ptr:最常用的引用计数
weak_pre:防止循环引用而设立的
2、explicit构造函数
每一个指针指针都有一个explicit构造函数,用explicit修饰构造函数的作用是禁止隐式转换或复制初始化。
3、类对象的初始化过程
类对象的新建:静态与动态。
类对象的初始化:1、默认初始化;2、直接初始化;3、拷贝初始化;4、值初始化。
必须使用初始化列表的场景:
a. 常量成员。常量只能初始化不能赋值,必须放在初始化列表里面。
b. 引用类型。引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面。
c. 没有默认构造函数的类类型。因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化
4、内联函数
a、直接使用,没有调用开销
b、不能包含循环与switch语句。
5、类型转换
const_cast:用于将const变量转为非const
static_cast:用于各种隐式转换,比如非const转const,void*转指针等, static_cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知;
dynamic_cast:用于动态类型转换。只能用于含有虚函数的类,用于类层次间的向上和向下转化。只能转指针或引用。向下转化时,如果是非法的对于指针返回NULL,对于引用抛异常。要深入了解内部转换的原理。
向上转换:指的是子类向基类的转换
向下转换:指的是基类向子类的转换
它通过判断在执行到该语句的时候变量的运行时类型和要转换的类型是否相同来判断是否能够进行向下转换。
reinterpret_cast:几乎什么都可以转,比如将int转指针,可能会出问题,尽量少用;
6、野指针
a. 未初始化的指针变量。
b. 指向的内存被释放没有置NULL的指针。
c. 超过了变量作用范围的指针
7、C++多态
静态多态:函数重载实现
动态多态:通过虚函数实现
8、构造函数为什么不能是虚函数
虚函数对应一个虚函数表,虚函数表是存在在对象的内存空间的,如果构造函数是虚函数,就需要有一个虚函数表来调用,但是类还没有实例化就没有内存空间,也就没有虚函数表。形成一个死循环。
9、基类虚构函数为什么是虚函数
a、动态多态。当父类指针指向子类对象,在析构时,编译器只知道这是一个父类指针,所以只将父类的内存进行了析构,而不会去析构子类的内存,造成了内存泄漏。
b、基类析构函数定义为虚拟函数的时候,在子类的对象的首地址开始会有一块基类的虚函数表拷贝,在析构子类对象的时候会删除此虚函数表,此时会调用基类的析构函数,所以此时内存是安全的。
c、C++默认的析构函数不是虚函数是因为虚函数需要额外的虚函数表和虚表指针,占用额外的内存。
10、函数指针与回调函数
指向函数地址的指针,常在回调函数中使用。
11、fork()函数
创建一个和当前进程映像一样的进程可以通过fork( )系统调用。
父进程调用返回子进程的进程号,子进程调用返回1,错误情况返回负数。
12、stick关键字
a、stick变量类相关,与对象无关。
b、多线程中,stick变量只会被初始化一次,即多线程中不会改变其值。
c、加了static关键字,则此变量/函数就没有了this指针了,必须通过类名才能访问。
13、resize()与reserve()
resize()改变容器大小,会导致容器内元素的增删。
reserve()仅改变容器的容量,不对对容器元素发生改变。
参考资料: