在c++开发过程中,经常需要记录对象的拥有者,因为只有其有责任删除该对象,即所有权的问题,为避免内存泄漏等问题,其他高级语言比如golang、java等实现了垃圾回收机制。在c++中可以通过实现引用计数来控制对象的生命周期,某种程度上也算是一种垃圾回收机制,如果面试吹牛时,你能这么个吹风,百万年薪不时梦(老套的广告语了)。
实际上,使用引用计数还有一目的:减少相同值对象的创建,比如java里的字符串string的字面值,当多个字面值一样时,不同的string对象实际上时指向同个内存地址。
Demo
#pragma once #include "RCObject.h" #include "RCPtr.h" using namespace Concurrency; class String { public: String(const char* initValue = "") :value(new StringValue(initValue)){ } const char& operator[](int index) const { return value->data[index]; }//只读 char& operator[](int index) { //已被共享时,不影响其他使用者,需使用新的副本 if (value->isShared()) { //Ptr的赋值构造函数会判断value的值是否需要释放 value = new StringValue(value->data); } value->markUnshareable(); return value->data[index]; } private: struct StringValue : public RCObject { char* data; StringValue(const char* initValue) { init(initValue); } StringValue(const StringValue& rhs) { init(rhs.data); } void init(const char* initValue) { data = new char[strlen(initValue) + 1]; strcpy(data, initValue); } ~StringValue() { delete[] data; } }; RCPtr<StringValue> value; };
以下为引用计数的实现
RCObject类
#pragma once #include <atomic> namespace Concurrency { using namespace std; class RCObject { private: std::atomic<int >refCount;//计数器 bool shareable;//是否共享 public: void addReference(); void removeReference(); void markUnshareable(); bool isShareable() const; bool isShared() const; protected: RCObject(); RCObject(const RCObject& rhs); RCObject& operator=(const RCObject& rhs); virtual ~RCObject() = 0;//纯虚函数 }; }
RCObject的实现
#include "RCObject.h" namespace Concurrency { RCObject::RCObject() : refCount(0), shareable(true) { } RCObject::RCObject(const RCObject& rhs):refCount(0), shareable(true) { } RCObject& RCObject::operator=(const RCObject& rhs) { // TODO: 在此处插入 return 语句 return *this; } void RCObject::addReference() { ++refCount; } void RCObject::removeReference() { if (--refCount == 0) delete this; } void RCObject::markUnshareable() { shareable = false; } bool RCObject::isShareable() const { return shareable; } bool RCObject::isShared() const { return refCount > 1; } };
RCPtr类
#pragma once namespace Concurrency { template<typename T>//template<class T> class RCPtr { private: T* pointee; void init(); public: RCPtr(T* realPtr = 0);//构造函数,默认值为0 RCPtr(const RCPtr& rhs);//拷贝构造函数, const表示被拷贝值不可修改 ~RCPtr(); RCPtr& operator=(const RCPtr& rhs);//赋值构造 //模拟指针操作符 T* operator->() const; T& operator*() const; }; }
RCPtr实现
#include "RCPtr.h" namespace Concurrency { template<typename T> void RCPtr<T>::init() { } template<typename T> Concurrency::RCPtr<T>::RCPtr(T* realPtr):pointee(realPtr) { init(); } template<typename T> Concurrency::RCPtr<T>::RCPtr(const RCPtr& rhs):pointee(rhs.pointee) { init(); } template<typename T> Concurrency::RCPtr<T>::~RCPtr() { if (pointee) pointee->removeReference(); } template<typename T> RCPtr<T>& Concurrency::RCPtr<T>::operator=(const RCPtr& rhs) { // TODO: 在此处插入 return 语句 if (pointee != rhs.pointee) { if (pointee) { pointee->removeReference(); } pointee = rhs.pointee; init(); } return *this; } template<typename T> T* Concurrency::RCPtr<T>::operator->() const { return pointee; } template<typename T> T& Concurrency::RCPtr<T>::operator*() const { // TODO: 在此处插入 return 语句 return *pointee; } }