c++ - 应该在哪里声明纯虚析构函数?

标签 c++ memory-leaks linker-errors virtual-destructor

编辑:显然问题的表述不够明确。我遇到的问题是,当在 header 中定义析构函数时,它会被添加到多个 .obj 文件中,并且链接器会提示。实际问题是:

当我将析构函数添加到 DLL 项目中的 CPP 文件并使用动态加载的 dll 和接口(interface)头文件时,是否仍会调用基本析构函数以防止内存泄漏?

我正在使用 MSVC 10.0 并有一个实现接口(interface)的 DLL 项目。该接口(interface)是一个抽象(纯虚拟)基类。这个想法是 header 与库的动态加载一起使用。因此,我使用了纯虚拟析构函数来确保调用基类中的析构函数。这是解释这一点的示例代码:

//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,这可能无法正常工作。

最佳答案

问题是基类析构函数总是 被调用——但在这种情况下,您已将其设为纯虚拟,因此它不存在。使析构函数成为纯虚拟的唯一原因是在没有其他成员时将类强制为抽象类。在所有情况下都需要定义类的析构函数。

编辑:我误读了您的代码。只需定义几乎内联的析构函数。

虚拟 ~ISplitter() {}

这里不需要任何纯虚拟,因为您已经有其他纯虚拟成员。

关于c++ - 应该在哪里声明纯虚析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6174785/

相关文章:

c++ - 复杂类型的 QVector 与 std::vector

Node.js AWS-SDK SQS 内存泄漏

c++ - 什么是 undefined reference /未解析的外部符号错误以及如何修复它?

c - Lapacke in C : using dsymm, 链接器错误

java - FFmpeg 链接器错误 : Error due to text relocations in libavcodec shared object

c++ - boost::process 在 Cygwin 中不起作用

c++ - 释放内存的重要性?

c++ - 从指针转换为非标量对象类型?

c++ - 正确释放 SDL_Surface?

node.js - 使用 Node 流时内存不足