C++内存管理

    C++之所以难使用除了语法太复杂之外,另一个原因就是内存管理需要程序员自己控制了。也正式因为拷贝构造函数的存在,使得很多时候,不注意就陷入了拷贝构造函数带来的空指针异常。所以尽量避免拷贝构造函数的使用,会使得内存管理更加方便,约定一些规范去使用C++,会使C++更加容易使用。

    使用引用计数来管理内存是一种常见的内存回收算法,也是比较容易实现的算法。下面就是一个简单的引用计数内存回收实现。

    我创建了一个基类,项目所有的自定义类必须继承该类,并且自定义类的拷贝构造函数必须设置为private。

    

//
// 通过引用计数来完成C++的自动内存回收,这是所有自定义类的基类
//

#ifndef CLUSTER_CHAT_HARDREFERENCE_H
#define CLUSTER_CHAT_HARDREFERENCE_H


#include <zconf.h>

class HardReference {
public:
    HardReference();
    virtual HardReference* obtain();
    virtual void release();
    virtual ~HardReference();
protected:
    uint mHardReferenceCount;

private:
    HardReference(HardReference* hardReference);
};


#endif //CLUSTER_CHAT_HARDREFERENCE_H



//
// 通过引用计数来完成C++的自动内存回收,这是所有自定义类的基类
//

#include "HardReference.h"

HardReference::HardReference() {
    this->mHardReferenceCount = 1;
}

/**
 * 注意,这个拷贝构造函数使用private修饰符,阻止了拷贝函数的调用
**/
HardReference::HardReference(HardReference *hardReference) {

}

HardReference::~HardReference() {
    this->mHardReferenceCount = 0;
}

/**
 * 如果想把自身拷贝给别人的话,只能通过指针方式传递出去,
 * 因为拷贝构造函数已经被设置为private,
 * 子类的拷贝构造函数也必须要设置为private
**/
HardReference* HardReference::obtain() {
    this->mHardReferenceCount++;
    return this;
}

/**
 * 添加(mHardReferenceCount > 0),防止多次析构函数的调用
**/
void HardReference::release() {
    if (this->mHardReferenceCount > 0) {
        this->mHardReferenceCount--;
        if (this->mHardReferenceCount <= 0) {
            delete this;
        }
    }

}



    在使用继承HardReference时,子类的拷贝构造函数必须是private的,如下:
//
// 继承HardReference,并把拷贝构造函数设置为private,必须通过指针传递
//

#ifndef CLUSTER_CHAT_SESSION_H
#define CLUSTER_CHAT_SESSION_H

#include "base/HardReference.h"

class Session : public HardReference{
public:
    Session(const char *message);
    void toString();
    ~Session();

protected:
    char* mMessage;

private:
    Session(Session &session);
};


#endif //CLUSTER_CHAT_SESSION_H



    在使用时,不要使用delete来主动调用对象的析构函数,而是通过obtain和release方法来获取指针引用和调用析构函数。通过这种方式避免存在有效指针引用的情况下,析构函数就被调用了。

    使用案例:

    

#include <iostream>
#include "Session.h"

using namespace std;

int main() {
    Session *session = new Session("Hello World!");
    Session *session1 = (Session*) session->obtain();
    session->toString();
    session->release();
    session1->toString();
    session1->release();
    return 0;
}


    每次的指针传递必须使用obtain来获取传递,而且obtain和release是成对出现的,这样有效的避免了内存泄露,而且内存的自动回收也得到实现。

你可能感兴趣的:(C++,内存回收,引用计数)