C++点滴

1.类成员初始化
使用初始化列表来进行C++初始化类成员,有一个重要特性,就是按照数据成员在类里的声明顺序进行初始化的,而不是按照出现在初始化列表中的顺序进行初始化。

2. 基类的析构函数必须写成虚函数
在编写Code的时候,建议将析构函数定义为虚函数。因为你不知道,也不确定正在使用的类,将来哪一天不会被扩展,将来哪一天不会被继承,不会被作为父类、基类。
将析构函数定义为虚函数,是最明智,最保险的一种做法,也是C++专家的惯用套路。

3. 重载(Overload)、覆盖(Override)、隐藏(Overwrite)3个概念
1)覆盖与隐藏的本质,就是基类函数不工作,工作的是派生类函数;
2)重载是针对参数不同(有无const也视为不同),构成重载的各个函数具有相同的作用域(如:同一类域),仅返回值不同,不构成重载;
3)覆盖是针对基类、派生类而言,也就是有继承关系的类而言,并且必须带virtual关键字,派生类函数和基类虚函数同名同参(多态);
4)隐藏是针对基类、派生类而言,也就是有继承关系的类而言。派生类和基类函数同名不同参,不论基类函数是否是vitrual,派生类函数被隐藏;派生类和基类非vitrual函数同名同参,基类函数被隐藏。只要不是覆盖,必然是隐藏。
区别:override覆盖的结果是根据对象类型决定调用哪个函数(多态);而Overwrite隐藏则表现为根据指针类型决定调用哪个函数。

4. volatile关键字
1)使用volatile关键字修饰的变量,可以避免编译器优化;
2)使用volatile关键字修饰的变量,每次都是重新读取内存中的值,而不是使用保存在寄存器里的值了
3)编译器优化的做法是:

int i = 5;
int a = i;
……
int b = i;

编译器发现两次从i读数据的代码之间,并没有对i进行过操作,它会自动把上次读的数据放在b中,而不是重新从i里面读。volatile可以避免此种优化。

5. static
普通的全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,普通的(也就是非静态)的全局变量在各个源文件中都是有效的。
而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
把局部变量改变为静态变量后,是改变了它的存储方式,即改变了它的生存期。
把全局变量改变为静态变量后,是改变了它的作用域, 限制了它的使用范围。
1). static 函数 主要用来限制作用域,只限本源文件有效 (可以避免重命名的问题);
2). 修饰全局变量, 限定在本源文件有效 ;
3). 修饰局部变量,延长生命周期(只被初始化一次,下次使用的依然是上一次的值);
4). C++ static 类成员变量.表示该变量为该类及该类的所有对象所属,值都是保持一致的。内存中只有一个副本。

6. 静态编译与动态编译
动态编译的可执行文件需要附带一个的动态链接库,在执行时,需要调用其对应动态链接库中的命令。
静态编译就是编译器在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库(.so)中的部分提取出来,链接到可执行文件中去,使可执行文件在运行的时候不依赖于动态链接库。

7. extern “C”
1). C语言中修饰在变量/函数,表示该变量/函数在别处已经定义,而在此处引用
2). extern “C” 是使C++能够调用C语言的库文件的一个手段

#ifdef __cplusplus
extern "C" {
#endif

/*
代码块....
*/

#ifdef __cplusplus
}
#endif

8. struct 和 class
1). struct的成员默认权限是public,而class的成员默认权限是private;
2). struct的默认继承方式为public,而class的默认继承为private;
3).“class”这个关键字还用于定义模板参数,就像“typename”。但关键字“struct”不用于定义模板参数;
4). struct赋值可以用{};class赋值用构造函数。

9. 栈 和 堆
1). 管理方式
栈:存放函数参数值、局部变量,编译器自动管理;
堆:程序员控制(new/delete 或 malloc/free)。
2). 生长方向
栈:高地址向低地址(向下);
堆:低地址向高地址,不连续,有碎片(向上)。
3). 空间大小
栈:由系统预先规定(一般默认2M或10M),小;
堆:受限于计算机中有效的虚拟内存(32位Linux系统可达到2.9G),大。
4). 存储内容
栈:在函数调用时,先压入主调函数中下条指令(函数调用语句的下一条可执行指令)地址,然后是函数实参,最后是被调函数的局部变量。本次调用结束,局部变量先出栈,然后是实参,最后栈顶指针指向刚开始存的下条指令的地址,程序执行该指令地址。
堆:通常在头部用一个字节存放其申请的空间大小(供后续释放使用)。存放生存期与函数调用无关的数据,具体内容由程序员控制。
5). 分配方式
栈:有静态分配和动态分配。静态分配由编译器完成,如局部变量。动态分配由alloca函数在栈上申请,用完后自动释放。
堆:只能动态分配(new/malloc),且手工释放(delete/free)。
6). 分配效率
栈:由计算机底层提供支持,分配专门的寄存器存放栈地址,压栈出栈由专门的指令执行,因此效率高。
堆:由函数提供,机制复杂,效率比栈低很多。Windows系统中VirtualAlloc可直接在进程地址空间分配一块内存,快速且灵活。
7). 分配后系统响应
栈:如果栈剩余空间小于申请空间,报告异常(提示栈溢出)。
堆:操作系统为堆维护一个记录空闲内存地址的链表,当操作系统收到程序申请内存的命令时,会遍历空闲内存地址链表,寻找到第一块大于申请空间的堆节点,然后将该节点从空闲内存地址链表删除,将此节点返回给程序。如果没有足够大小的空间(碎片过多),有可能调用系统功能,增加程序数据段的大小。由于找到的堆节点的大小不一定刚好等于申请的大小,系统自动将多余的部分重新放回空闲链表。
8). 碎片问题
栈:没碎片。先进后出。
堆:有碎片。频繁申请内存,造成堆剩余空闲空间不连续,出现大量碎片,效率降低。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值