C++ 中的虚拟默认析构函数
Posted
技术标签:
【中文标题】C++ 中的虚拟默认析构函数【英文标题】:Virtual Default Destructors in C++ 【发布时间】:2010-10-24 01:18:27 【问题描述】:我有大量继承自基类(标准)的继承类(标准)。这是criterion
的代码
class criterion
public:
virtual unsigned __int32 getPriorityClass() const = 0;
virtual BOOL include(fileData &file) const = 0;
virtual void reorderTree() = 0;
virtual unsigned int directoryCheck(const std::wstring& directory) const = 0;
virtual std::wstring debugTree() const = 0;
;
这个派生类的一些例子:
class fastFilter : public criterion
public:
void reorderTree() ;
unsigned int directoryCheck(const std::wstring& /*directory*/) const return DIRECTORY_DONTCARE; ;
unsigned __int32 getPriorityClass() const return PRIORITY_FAST_FILTER; ;
;
class isArchive : public fastFilter
public:
BOOL include(fileData &file) const
return file.getArchive();
std::wstring debugTree() const
return std::wstring(L"+ ISARCHIVE\n");
;
;
由于我这里根本没有析构函数,但这应该是一个基类,我是否需要插入一个空的虚拟析构函数,即像这样?:
virtual void ~criterion() = 0;
如果需要虚拟析构函数声明,是否所有中间类也都需要一个? IE。上面的 fastFilter 是否也需要一个虚拟析构函数?
【问题讨论】:
上面不是空的析构函数。它是一个析构函数,也是一个纯虚函数。这与为空无关,事实上析构函数的特殊之处在于它必须始终有一个定义,即使它是纯虚拟的。 【参考方案1】:是的 - 基类需要一个虚拟析构函数,即使它是空的。如果不这样做,那么当 delete
通过基指针/引用作为派生对象时,派生对象的成员对象将没有机会正确地销毁自己。
派生类不需要声明或定义自己的析构函数,除非它们需要默认析构函数行为以外的东西。
【讨论】:
为什么不将其标记为默认值?而不是“= 0”放下“=默认”【参考方案2】:建议插入:
virtual ~criterion()
从 C++11 开始,您可以使用 = default;
代替空主体 。
这是为了避免从基类的指针中删除问题。否则你会泄漏内存,因为派生类的析构函数不会被调用。
criterion *c = new fastFilter();
delete c; // leaks
【讨论】:
有什么理由使用空析构函数而不是纯虚拟析构函数?virtual ~criterion() noexcept
不是更漂亮吗?
@user1095108,virtual ~criterion() = default
不是更漂亮吗?
@user35443:“=default”在 2009 年不存在。它是在 C++11 中添加的。是的,现在我认为这将是首选。
@Pacheco 啊,看来三年前我没有注意到答案是在 09 年写的。哎呀,时间过得真快……【参考方案3】:
你不需要把析构函数抽象化,给它一个空实现即可:
virtual ~criterion()
这样您就不必在每个子类中都实现它,但每个子类仍然会有一个(继承的)虚拟析构函数。
【讨论】:
【参考方案4】:与其他人已经回答的一个小变化:
代替
virtual void ~criterion() = 0;
要求的版本是:
virtual ~criterion() //Note: Removed void as destructors not allowed
// a return type
要了解有关虚拟析构函数的更多信息,请查看 FAQ When should my destructor be virtual? 中的此链接
【讨论】:
以上是关于C++ 中的虚拟默认析构函数的主要内容,如果未能解决你的问题,请参考以下文章
C++ 虚拟析构函数 (virtual destructor)