C++ 强/弱指针

  • 引用计数法

  • 强指针 会修改引用计数。弱指针,不会修改引用计数

  • 参考 https://www.cnblogs.com/hellokitty2/p/10646353.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    #include <iostream>

    using namespace std;
    //参考 https://www.cnblogs.com/hellokitty2/p/10646353.html

    //基类实现 引用的计数的功能
    // 缺陷 这是非线程安全的
    class RefBase {
    private:
    int refcount = 0;
    public:
    RefBase() {}

    void incStrong(void) {
    refcount++;
    }

    void decStrong(void) {
    refcount--;
    }

    int getStrong(void) {
    return refcount;
    }
    };


    //模板类 实现 指针引用其他类,
    // 因为需要调用对象的方法,所以其他类需要实现基类
    template<typename T>
    class sp {
    private:
    T *p;
    public:
    sp() : p(NULL) {
    cout << "sp()" << endl;
    }

    //构造函数 引用加一
    sp(T *p) {
    cout << "sp(T *p)" << endl;
    this->p = p;
    this->p->incStrong();
    }
    //拷贝函数 引用加一
    sp(const sp &other) {
    cout << "sp(const sp & other)" << endl;
    this->p = other.p;
    this->p->incStrong();
    }

    //析构函数 引用减一
    ~sp() {
    cout << "~sp()" << endl;
    this->p->decStrong();

    // 当引用减少到0的时候 就释放对象
    if (!this->p->getStrong()) {
    delete p; //自动调用 ~Person()
    cout << "delete p" << endl;
    }
    }

    //操作符重载,对指针sp调用的时候,等价于p在调用
    T *operator->() {
    return this->p;
    }
    //操作符重载,对指针sp调用的时候,等价于p在调用
    T &operator*() {
    return *(this->p);
    }
    };


    class Person : public RefBase {
    public:
    Person() {
    cout << "Person()" << endl;
    }
    ~Person() {
    cout << "~Person()" << endl;
    }
    };

    int main() {
    cout << "";
    sp<Person> p1 = new Person();
    sp<Person> p2 = p1;
    }
  • log

    1
    2
    3
    4
    5
    6
    7
    Person()
    sp(T *p)
    sp(const sp & other)
    ~sp()
    ~sp()
    ~Person()
    delete p

C++内存管理

  • new/delete是C++的操作符,而malloc/free是C中的函数
  • new/delete是保留字,不需要头文件支持;malloc/free需要头文件库函数支持
  • free只是释放了malloc所申请的内存,并没有改变指针的值
  • new 做了2件事。先申请空间,再调用构造函数。
  • delete 做了2件事件。先调用析构函数,再释放空间。
  • 注意 new[] 与 delete[] 配对使用,如果先 ptr=new object[] 创建多个对象,直接调用 delete ptr,只会调用和释放一个,剩下的不会释放,造成内存泄漏。
    1
    2
    3
    Cat * ptr= new Cat[5];
    delete(ptr);//错误,只会回收一个
    delete[] (ptr);//正确