C 类设计 - 如何在基类驱动器中清理

C++ Class Design - how to clean up in base-class destructor

本文关键字:驱动器 基类      更新时间:2023-10-16

我很难在框外思考以下问题。我有一个类层次结构:

[BaseClass] --> [Win32Class]

[BaseClass] --> [LinuxClass]

[BaseClass] --> [VxWorksClass]

实现类将调用API级功能。这些是在基类中纯虚拟函数内完成的。

现在,当用户创建,使用并使用对象完成时,他应该调用Done函数(来自基类),该功能将进行清理和资源脱位。此清理的一部分是调用许多API级功能 - 这些自然是基类中的纯虚拟功能,并在派生类中实现。到目前为止还不错。

这是问题。如果用户明确调用Done,则由于资源未正确释放,将会有各种内存泄漏。因此,我认为我会变得容易,并从~BaseClass()调用Done-我想自动清理破坏。好吧,不是那么多。由于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
  }
};

========================================
这是我的解决方案。使用包装器类。在Win32ClassBaseClass的破坏者中呼叫Done

class Win32Wrapper{
public:
  Win32Class* object_;
public:
  Win32Wrapper(){
    this->object_ = new Win32Class;
  }
  ~Win32Wrapper(){
    this->object_->Done();
    delete this->object_;
  }
};

==如何在destructor中调用纯虚拟==

class Base{
public:
  Base(){
  }
  virtual ~Base(){
    Done();
  }
  void Done(){
    Clean();
  }
  virtual void Clean() = 0;
};
class Derived : public Base{
public:  
  Derived(){
  }
  ~Derived(){
  }
  virtual void Clean(){
  }
};

用户认为该程序会起作用,因为编译器不抱怨Base::Done()中的PFV的呼叫。

您可以将清理代码放在派生的破坏者中:

struct Base
{
    virtual ~Base() { }
    void CleanUp() { /* ... */ }
};
struct Derived : Base
{
    virtual ~Derived()
    {
        CleanUp();
    }
};

如果需要,您甚至可以将呼叫打电话到非虚拟Base::CleanUp()函数中以允许特定于派生的行为(尽管通过您的描述,听起来您不需要)。

<</p> <</p>

我认为raii习惯是您想要的。

您可以在此处找到一个非常全面的描述:http://www.hackcraft.net/raii/

您有两个选项。

  1. BaseClass的用户必须致电Done(),而由于不这样做的任何错误都是他的责任。
  2. 每个派生的类都可以在其毁灭者中执行任何清理。他们可以在清理中使用BaseClass功能,并且BaseClass功能甚至可以调用被派生类覆盖的功能。