应该在哪里声明纯虚拟析构函数
Where should the pure virtual destructor be declared?
EDIT:显然这个问题表述得不够清楚。我遇到的问题是,当在头中定义析构函数时,它会被添加到多个.obj文件中,而链接器会抱怨。实际问题是:
当我将析构函数添加到DLL项目中的CPP文件并使用动态加载的DLL和接口头文件时,是否仍会调用基本析构函数以防止内存泄漏?
我使用的是MSVC 10.0,并且有一个实现接口的DLL项目。接口是一个抽象的(纯虚拟的)基类。其思想是头与库的动态加载一起使用。因此,我使用了一个纯虚拟析构函数来确保基类中的析构函数被调用。以下是解释这一点的示例代码:
//ISplitter.h
#pragma once
struct param {
int something;
}
class ISplitter {
public:
virtual ~ISplitter() = 0;
virtual void useful() = 0;
}
ISplitter::~ISplitter() {
/* Make sure base class destructor gets called */
}
和主要实现头
//CSplitter.h
#pragma once
#include "CHelper.h"
#include "ISplitter.h"
class CSplitter : public ISplitter {
private:
CHelper hlp;
public:
~CSplitter();
void useful();
}
一些辅助类
//CHelper.h
#pragma once
#include "ISplitter.h" // I need the struct
// Class definition should go here but is irrelevant
现在的问题是链接器生成一个错误,告诉我析构函数:ISplitter::~ISplitter(void)已被多重声明,系统将不会生成。错误:
CHelper.obj : error LNK2005: "public: virtual __cdecl ISplitter::~ISplitter(void)" (??1ISplitter@@UEAA@XZ) already defined in CSplitter.obj
解决此问题的正确方法是什么?我已经在ISplitter.cpp中放置了析构函数,但我担心如果我动态加载库并将基类向上转换到ISplitter,这可能不会起作用。
问题是基类析构函数总是被调用,但在这种情况下,您已经使它成为纯虚拟的,所以它不存在。使析构函数纯虚拟化的唯一原因是在没有其他成员的情况下强制类是抽象的。在任何情况下都需要定义类的析构函数。
编辑:我读错了你的代码。只需以内联方式定义析构函数。
virtual ~ISplitter() {}
这里不需要任何纯虚拟成员,因为您已经有了其他纯虚拟成员。
Sharptooth的答案是正确的,因为您必须为纯虚拟析构函数提供一个定义(请参阅GotW)。但这是错误的,因为你不能写
virtual ~A() = 0 {};
根据标准中的此条款(尽管许多编译器支持此扩展)
C++03第10.4条第2款告诉我们什么是抽象类,作为补充说明,如下所示:
[注意:函数声明不能同时提供纯说明符和定义--尾注][示例:
struct C {
virtual void f() = 0 { }; // ill-formed
};
-结束示例]
请参阅我的这个问题以了解更多详细信息
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 是否可以使用函数指针调用虚拟析构函数?
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- 程序永远不会进入虚拟析构函数
- C++ std::vector 中的虚拟析构函数继承
- 哪种方法更适合处理虚拟析构函数?
- 拥有"受保护的非虚拟析构函数"与"受保护虚拟析构构函数"有什么好处
- 带有未解析外部元素的C++虚拟析构函数
- 即使基类和派生类只使用基元数据类型,我是否需要定义虚拟析构函数
- C++切片和虚拟析构函数
- C++虚拟继承、虚拟析构函数和 dynamic_cast<void*>
- 添加虚拟析构函数会使代码大小膨胀
- 应该是虚拟析构函数吗?但是怎么做呢?
- 虚拟析构函数将对象移出 rodata 部分
- 如何将 std::unique_ptr<Parent> 与具有受保护虚拟析构函数的只读父类一起使用
- DIRECTX9 中自定义顶点的虚拟析构函数
- 为什么缺少虚拟析构函数不会导致内存泄漏?
- std::unique_ptr 在虚拟析构函数上重置 SIGABRT
- C++11 中默认纯虚拟析构函数的正确放置
- 在派生类中重写哪个基类的虚拟析构函数