C 类设计 - 如何在基类驱动器中清理
C++ Class Design - how to clean up in base-class destructor
我很难在框外思考以下问题。我有一个类层次结构:
[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
}
};
========================================
这是我的解决方案。使用包装器类。在Win32Class
或BaseClass
的破坏者中呼叫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()
函数中以允许特定于派生的行为(尽管通过您的描述,听起来您不需要)。
我认为raii习惯是您想要的。
您可以在此处找到一个非常全面的描述:http://www.hackcraft.net/raii/
您有两个选项。
-
BaseClass
的用户必须致电Done()
,而由于不这样做的任何错误都是他的责任。 - 每个派生的类都可以在其毁灭者中执行任何清理。他们可以在清理中使用
BaseClass
功能,并且BaseClass
功能甚至可以调用被派生类覆盖的功能。
- std::具有相同基类的类的变体
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 基类中的函数名称解析
- C++初始化基类
- 如何通过派生类函数更改基类中的向量
- 如何定义一个纯抽象基类
- 如何使用基类指针引用派生类成员
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 如果基类包含双指针成员,则派生类的构造函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 为什么此派生对象无法访问基类的后递减方法?
- 公开最直接的基类模板名称
- 当基类是依赖类型时,这是一个缺陷吗
- 如何使基类的运算符对基类的可变参数数可见(请参阅下面的代码)?
- 模板基类中的静态变量
- C 类设计 - 如何在基类驱动器中清理
- 在派生的类构造函数中抛出例外.为什么要称呼基类驱动器,但未派生的类驱动器