对于以下问题,我无法跳出框框思考。我有一个类层次结构:
[BaseClass] --> [Win32Class]
[BaseClass] --> [LinuxClass]
[BaseClass] --> [VxWorksClass]
实现类将调用 API 级函数。这些是在基类的纯虚函数中完成的。
现在,当用户创建、使用并完成对象时,他应该调用该Done
函数(来自基类),该函数将进行清理和资源释放。这种清理工作的一部分是调用一些 API 级函数——这些自然是基类中的纯虚函数,并在派生类中实现。到目前为止,一切都很好。
这就是问题所在。如果用户没有显式调用Done
,则会由于资源没有被正确释放而导致各种内存泄漏。所以,我想我会让它变得简单并调用- 破坏时自动清理,我想Done
。~BaseClass()
好吧,没有那么多。由于Done
对这些纯虚拟的调用,所有地狱都崩溃了。
关于如何重新设计它以避免这个问题的任何想法?
示例代码
class BaseClass{
virtual ~BaseClass(){
Done();
}
void Done(){
// A bunch of OS-independent clean-up logic
Cleanup();
// some more OS-independent clean-up logic
}
virtual void Cleanup() = 0;
};
class Win32Class : public BaseClass{
virtual void Cleanup(){
// call some Win32-specific cleanup code
}
};
class LinuxClass : public BaseClass{
virtual void Cleanup(){
// call some Linux-specific cleanup code
}
};
===========================================
这是我的解决方案。使用包装类。不要调用orDone
的析构函数Win32Class
BaseClass
class Win32Wrapper{
public:
Win32Class* object_;
public:
Win32Wrapper(){
this->object_ = new Win32Class;
}
~Win32Wrapper(){
this->object_->Done();
delete this->object_;
}
};
== 如何在析构函数中调用 Pure Virtuals ==
class Base{
public:
Base(){
}
virtual ~Base(){
Done();
}
void Done(){
Clean();
}
virtual void Clean() = 0;
};
class Derived : public Base{
public:
Derived(){
}
~Derived(){
}
virtual void Clean(){
}
};
用户认为该程序可以运行,因为编译器不会抱怨对 PFV in 的调用Base::Done()
。