EDIT: Apparently the question is not clearly formulated enough. The issue I am having is that when the destructor is defined in the header it gets added into multiple .obj files and the linker complains. The actual question is:
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?
I am using MSVC 10.0 and have a DLL project that implements an interface. The interface is an abstract (pure virtual) base class. The idea is that the header is used with dynamic loading of the library. Therefore, I have used a pure virtual destructor to make sure the destructor in the base class gets called. Here is sample code to explain this:
//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 */
}
And the main implementation header
//CSplitter.h
#pragma once
#include "CHelper.h"
#include "ISplitter.h"
class CSplitter : public ISplitter {
private:
CHelper hlp;
public:
~CSplitter();
void useful();
}
Some helper class
//CHelper.h
#pragma once
#include "ISplitter.h" // I need the struct
// Class definition should go here but is irrelevant
Now the problem is that the linker generates an error that tells me the destructor: ISplitter::~ISplitter(void) has been multiply declared and the system will not build. Error:
CHelper.obj : error LNK2005: "public: virtual __cdecl ISplitter::~ISplitter(void)" (??1ISplitter@@UEAA@XZ) already defined in CSplitter.obj
What is the correct way to fix this? I have placed the destructor in ISplitter.cpp, but I am worried this may not work if I dynamically load the library and upcast the base class to ISplitter.
The problem is that the base class destructor always gets called- but in this case, you've made it pure virtual, so it doesn't exist. The only reason to make a destructor pure virtual to is to enforce a class to be abstract when you have no other members. The destructor of a class needs to be defined in all cases.
Edit: I mis-read your code. Just define the destructor virtually inline.
virtual ~ISplitter() {}
There's no need for any pure virtual here, since you already have other pure virtual members.
Sharptooth's answers is correct in that you HAVE to provide a definition to the pure virtual destructor (see this GotW). But it is wrong in that you cannot write
virtual ~A() = 0 {};
according to this clause in the standard (although many compilers support this extension)
Clause 10.4 paragraph 2 of C++03 tells us what an abstract class is and, as a side note, the following:
[Note: a function declaration cannot provide both a pure-specifier and a definition —end note] [Example:
struct C {
virtual void f() = 0 { }; // ill-formed
};
—end example]
See this question of mine for more details
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With