zoukankan      html  css  js  c++  java
  • 13C++11提高类型安全.md

    1. 强类型枚举
    //c++11的强类型枚举可以指定底层基于的基本类型,我们可以避免编译器不同而带来的不可移植性。
    //另外,设置较小的基本类型也可以节省内存空间。
    enum  class C : char {C1 = 1, C2 = 2};
    enum class D : unsigned int {D1 = 1, D2 = 2, Dbig = 0xFFFFFFF0U};
    cout << "sizeof(C):" << sizeof(C) << endl;			//1
    cout << "sizeof(C::C1):" << sizeof(C::C1) << endl;	//1
    cout << "sizeof(D::D1)" << sizeof(D::D1) << endl;	//4
    
    2. 堆内存管理:智能指针与垃圾回收
    2.1 显式内存管理

    ​ 从语言层面来讲,c++中内存相关的问题可以归纳为三个方面。

    • 野指针:一些内存单元已被释放,之前指向它的指针却还在被使用。这些内存有可能被运行时系统重新分配给程序使用,从而导致了无法预测的错误。
    • 重复释放:程序试图去释放已经被释放过的内存单元,或者释放已经被重新分配过的内存单元,就会导致重复释放错误。通常重复释放内存会导致 c/c++ 运行时系统打印出大量错误及诊断信息。
    • 内存泄漏:不再需要使用的内存单元如果没有被释放就会导致内存泄漏。如果程序不断重复进行这类操作,将会导致内存占用剧增。
    2.2. C++11 智能指针
    void testUniquePtr()
    {
    cout << "enter testUniquePtr()...................................................................." << endl;
    	unique_ptr<int> up1(new int(1));
    	//unique_ptr<int> up2 = up1;		//编译失败,unique_ptr所指对象的内存的所有权只能通过标准库的 move 函数来转移
    	unique_ptr<int> up2 = move(up1);	//up2是数据唯一的 unique_ptr 智能指针
    	cout << "*up2:" << *up2 << endl;
    	unique_ptr<int> up3(move(up2));
    	cout << "*up3:" << *up3 << endl;
    	up1.reset();
    	up2.reset();
    	up3.reset();
    	cout << "return from testUniquePtr()...................................................................." << endl;
    }
    

    ​ 从实现上讲, unique_ptr 是一个删除了拷贝构造函数、保留了移动构造函数的指针封装类型。程序员仅可以使用右值对 unique_ptr 对象进行构造,而且一旦构造成功,右值对象中的指针即被“窃取”,因此该右值对象即刻失去了对指针的“所有权”。

    shared_ptr<int> sp1(new int(22));
    shared_ptr<int> sp2 = sp1;
    auto sp3 = sp1;
    cout << "*sp1:" << *sp1 << endl;	//22
    cout << "*sp2:" << *sp2 << endl;	//22
    sp1.reset();
    cout << "*sp2:" << *sp2 << endl;	//22
    cout << "*sp3:" << *sp3 << endl;	//22
    sp2.reset();
    cout << "*sp3:" << *sp3 << endl;	//22
    

    ​ 而 shared_ptr 同样形如其名,允许多个该智能指针共享地“拥有”同一堆分配对象的内存。与 unique_ptr 不同的是,由于在事项上采用了引用计数,所以一旦一个 shard_ptr 指针放弃了“所有权”,其他的 shared_ptr 对对象内存的引用并不会受影响。某个智能指针调用 reset 知会导致引用计数的降低,不会导致堆内存的释放。

    2.3 垃圾回收的分类

    ​ 我们把之前使用过,现在不再使用或者没有任何指针再指向的内存空间就称为 “垃圾”。而将这些 “垃圾”收集起来以便再次利用的机制,就被称为“垃圾回收”。

    ​ 在当前流行的编程语言中,除过 c 和 Pascal 不支持,c++ 部分支持外,其他语言大多都支持自动回收。

    ​ 垃圾回收的方式虽然很多,但主要可以分为两大类:

    (1)基于引用计数的垃圾回收器

    ​ 简单地说,引用计数主要是使用系统记录对象被引用(引用、指针)的次数。当对象被引用的次数变为 0 时,该对象即被视作 “垃圾”而回收。使用引用计数做垃圾回收的算法的一个优点是实现很简单,与其他垃圾回收算法相比,该方法不会造成程序暂停,因为技术的增减与对象的使用是紧密结合的。此外,引用计数也不会对系统的缓存或者交换空间赞成冲击,因此被认为“副作用”较小。但是这种方法比较难处理“环形引用”问题,此外由于技术带来的额外开销也并不小,所以在使用上也有一定的限制。

    (2)基于跟踪处理的垃圾回收器

    ​ 相比于引用计数,跟踪处理的垃圾回收机制被更广泛地引用。器基本方法是产生跟踪对象的关系图,然后进行垃圾回收。使用跟踪方式的垃圾回收算法主要有以下几种:

    • 标记-清除
    • 标记-整理
    • 标记-拷贝
    2.4 c++ 与垃圾回收

    ​ 指针的灵活性使用可能是 c/c++ 中的一大优势,而对于垃圾回收来说,却会带来很大的困扰。

  • 相关阅读:
    从零开始学Electron笔记(二)
    从零开始学Electron笔记(一)
    Java 从入门到进阶之路(二十九)
    Java 从入门到进阶之路(二十八)
    Java 从入门到进阶之路(二十七)
    Java 从入门到进阶之路(二十六)
    Java 从入门到进阶之路(二十五)
    Java 从入门到进阶之路(二十四)
    Java 从入门到进阶之路(二十三)
    Java 从入门到进阶之路(二十二)
  • 原文地址:https://www.cnblogs.com/rock-cc/p/13415410.html
Copyright © 2011-2022 走看看