【发布时间】:2009-03-23 21:47:22
【问题描述】:
我刚刚被一个错误所困扰,部分原因是我缺乏理解,部分原因是我认为我们的代码库中的设计欠佳。我很好奇如何改进我的 5 分钟解决方案。
我们正在使用引用计数的对象,在这些类的对象上我们有 AddRef() 和 Release()。一个特定的对象派生自 ref-count 对象,但获取这些对象实例的常用函数 (GetExisting) 将 AddRef() 隐藏在其自身内部,而不宣传它正在这样做。这需要在功能块的末尾执行 Release 以释放隐藏的 ref,但是没有检查 GetExisting() 实现的开发人员不会知道这一点,并且忘记在末尾添加 Release 的人该函数(例如,在修复错误的关键时刻)会泄漏对象。这当然是我的烧伤。
void SomeFunction(ProgramStateInfo *P)
{
ThreadClass *thread = ThreadClass::GetExisting( P );
// some code goes here
bool result = UseThreadSomehow(thread);
// some code goes here
thread->Release(); // Need to do this because GetExisting() calls AddRef()
}
所以我写了一个小类来避免在这些函数的末尾需要 Release()。
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
ThreadClass * Thread() const { return m_T; }
};
所以现在我可以这样做了:
void SomeFunction(ProgramStateInfo *P)
{
ThreadContainer ThreadC(ThreadClass::GetExisting( P ));
// some code goes here
bool result = UseThreadSomehow(ThreadC.Thread());
// some code goes here
// Automagic Release() in ThreadC Destructor!!!
}
我不喜欢的是,要访问线程指针,我必须调用ThreadContainer的一个成员函数,Thread()。是否有一些聪明的方法可以清理它以使其在语法上更漂亮,或者类似的东西会模糊容器的含义并为不熟悉代码的开发人员引入新问题?
谢谢。
【问题讨论】: