1、强类型枚举
C语言 | 【耗费一夜总结三本C语言系列】之 结构体、联合、枚举
枚举一般用来定义一个类别;
【匿名枚举】:阔以用于定义数值的名字;
- 阔以使用const static代替,带该方式会占用较多的存储空间;
【具名枚举】:即有名字的枚举类型,该成员名字是全局可见的;
非强类型枚举的缺陷
- 1.当两个枚举内的成员相同时,由于该成员是全局的,故在使用时会造成混淆,报错;
namespace T {
enum Type { General, Light, Medium, Heavy };
}
namespace {
enum Category{ General = 1, Pistol, MachienGun, Cannon };
}
int main() {
T:T::Type t = T::Light;
if(t == General) {
cout << "-----" << endl;
}
return 0;
}
- 2.枚举成员总是阔以被隐式转换为整型
如何解决上述问题呢
【方法一】:使用class对其进行封装,但带来了其他缺点;
- 变得复杂;
- 采用静态成员,变成了非POD;
- 在参数传递等过程,造成性能损失;
【方法二】:C++11采用强类型枚举,在enum后加上一个class;
- 强作用域,不会被输出到父作用域;
- 转化限制,不能被隐式转换,比较需要通过显示转换;
- 可以指定底层类型,在枚举名称后加上`: type`,type不能为wchar_t;
enum class Type : char { General, Light, Medium, Heavy };
enum class Category { General = 1, Pistol, MachienGun, Cannon };
void test() {
Type t = Type::Light;
t = General;
if (t == Category::General) {}
if (t == Type::Light) {}
if((int)t > 0) {}
}
2、堆内存管理
C++ |【总结归纳三本书籍系列】一文透彻资源管理,动态内存分配【上】… C++【内存管理】| 【智能指针】动态内存管理
内存常见错误:
- 野指针:被使用的指针还在使用;
- 重复释放资源:对一个内存单元,多次释放;
- 内存泄漏:不在使用的内存,如果没有及时释放;
2.1 垃圾回收方式
基于引用计数
通过引用计数来记录对象被引用的次数;当其为0时,即释放;
- 副作用较小,一般实现较简单,但开销不小;
- 但是难以处理环形引用,在实用上有一定的限制;
基于跟踪处理
【标记-清除】:将当前使用对象视为根对象,从根对象查找它们所引用的堆空间,再此类堆空间上做标记;其中被标记上的为活对象,而没有被标记的则被
视为垃圾,再第二步被清除;
- 此类活对象不会移动,将会造成大量的内存碎片;
【标记-整理】:标记完后,为了解决上述出现内存碎片问题,将活对象往左靠;
- 移动时,必须对堆内存的引用都更新;
【标记-拷贝】:将堆空间分为两部分:From和To;系统开始将只从From分配,当分配完了,开始系统回收,从From中堆空间找出所有活对象,拷贝到To,
在将两者交换一次;
2.2 C++11与最小垃圾回收支持
C++11中,最小垃圾回收支持是基于安全派生指针(get_pointter_safety查看);
【安全派生指针】:
- 在解引用基础上的引用(&*p);
- 定义明确的指针操作(p+1);
- 定义明确的指针转换(static_cast<void*>(p));
- 指针和整型之间的reinterpret_case;
需要声明该内存为可到达,故会被回收期忽略而不被回收(declare_reachable);
消除可达声明(declare_reachable);
|