【发布时间】:2016-11-05 20:51:48
【问题描述】:
好的,我正在尝试使用引用计数的概念在 C++(一个非常基本的)中实现一个垃圾收集器,它可以工作,但是有一些我不明白的地方。
我有两节课:
#include <iostream>
using namespace std;
class GC {
public:
GC(){
this->refCount = 0;//Initialisation du compteur à zero
}
void incrementRef(){
this->refCount++;//Incrémentation du compteur de references
}
int decrementRef(){
return this->refCount--;//Décrementation du compteur de references
}
int getCounter(){//Getter du compteur de references
return refCount;
}
~GC(){}
private:
int refCount; //Compteur de references
};
TObject.cpp:
#include <iostream>
#include "GC.cpp"
using namespace std;
template <class T>
class TObject {
T *p;
GC *gc;
public:
TObject(T *p){
cout<<"refobject"<<endl;
this->p = p;
gc = new GC();
this->gc->incrementRef();
}
virtual ~TObject(){//Destructeur
cout<<"delete TObject"<<endl;
if(this->gc->decrementRef() == 0){
delete p;
delete gc;
}
}
T* operator->(){//Surcharge de l'opérateur d'indirection
return p;
}
T& operator*() const {//Surchage de l'opérateur
return *p;
}
TObject<T>& operator=(const TObject<T> &t){
if(this->gc->decrementRef() == 0){
delete p;
delete gc;
}
this->p = t.p;
this->gc = t.gc;
this->gc->incrementRef();
return *this;
}
GC getGC(){
return *gc;
}
};
这里是我如何在 main 中测试它的:
TObject<int> t(new int(2));
cout<<"t1 counter: "<<t.getGC().getCounter()<<endl;//Displays 1
TObject<int> t2(NULL);
cout<<"t2 counter: "<<t2.getGC().getCounter()<<endl;//Displays 1
t2 = t;
cout<<"t1 counter: "<<t.getGC().getCounter()<<endl;//Displays 2, why?
cout<<"t2 counter: "<<t2.getGC().getCounter()<<endl;//Displays 2
我不明白,我在 t2 中复制了 t,但我没有更新 t1!为什么它的引用计数器也更新了?
【问题讨论】:
-
您知道我们已经有
std::shared_ptr用于引用计数内存/生命周期管理吗? -
是的,但只是想知道它是如何工作的
-
您需要阅读 Eric Lippert 的[如何调试小程序]{ericlippert.com/2014/03/05/how-to-debug-small-programs) 自行回答。
-
您的 TObject 类需要一个复制构造函数以及赋值(阅读“3 规则”)。您的赋值运算符应该使用“复制和交换” - 它可以避免在将对象分配给自身时出现问题(通常是偶然的)。它还使异常安全更容易。
标签: c++ garbage-collection smart-pointers reference-counting