繁体   English   中英

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

[英]Where should the pure virtual destructor be declared?

编辑:显然这个问题的表述不够清楚。 我遇到的问题是,当在 header 中定义析构函数时,它会被添加到 multiple.obj 文件中,并且 linker 会抱怨。 实际的问题是:

When I add the destructor to a CPP file in a DLL project and use the dll with dynamic loading and the interface header file, does the base destructor still get called to prevent leaking memory?

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

//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 */
}

以及主要实现header

//CSplitter.h
#pragma once
#include "CHelper.h"
#include "ISplitter.h"


class CSplitter : public ISplitter {
private:
    CHelper hlp;
public:
    ~CSplitter();
    void useful();
}

一些帮手 class

//CHelper.h
#pragma once
#include "ISplitter.h" // I need the struct

// Class definition should go here but is irrelevant

现在的问题是 linker 生成一个错误,告诉我析构函数: ISplitter::~ISplitter(void) 已被多次声明,系统将无法构建。 错误:

CHelper.obj : error LNK2005: "public: virtual __cdecl ISplitter::~ISplitter(void)" (??1ISplitter@@UEAA@XZ) already defined in CSplitter.obj

解决此问题的正确方法是什么? 我已将析构函数放在 ISplitter.cpp 中,但我担心如果我动态加载库并将基础 class 上载到 ISplitter,这可能不起作用。

问题是基本的 class 析构函数总是被调用——但在这种情况下,你已经把它变成了纯虚拟的,所以它不存在。 使析构函数纯虚拟的唯一原因是在没有其他成员时强制 class 是抽象的。 在所有情况下都需要定义 class 的析构函数。

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

virtual ~ISplitter() {}

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

Sharptooth 的答案是正确的,因为您必须为纯虚拟析构函数提供定义(请参阅此 GotW )。 但这是错误的,你不能写

virtual ~A() = 0 {};

根据标准中的这个条款(尽管许多编译器支持这个扩展)

C++03 的第 10.4 条第 2 段告诉我们抽象 class 是什么,作为旁注,以下内容:

[注意:function 声明不能同时提供纯说明符和定义——尾注] [示例:

struct C {
virtual void f() = 0 { }; // ill-formed
};

——结束示例]

有关更多详细信息,请参阅我的这个问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM