Re: private destructor and templates
Ben Voigt wrote:
I have a POD type with a private destructor. There are a whole hierarchy of
derived POD types, all meant to be freed using a public member function
Destroy in the base class. I get warning C4624. I read the description,
decided that it's exactly what I want, and ignored the warning.
As said by others, your class becomes a non-POD as soon as you declare a
destructor. Additionally, derived classes are never POD types.
Now I'm trying to inherit using a template. Instead of "destructor could
not be generated because a base class destructor is inaccessible", I now
have an error C2248 <name of base destructor> "cannot access private
member". Is this correct or a bug?
It depends on whether your code is attempting to use the derived class
destructor (e.g. a call to delete will do that).
I don't want the compiler to generate a
destructor for the base class,
But you've written a destructor - it even does something (calls
FreeAgent();).
I won't declare any variables on the stack
and I will use the base Destroy function to deallocate it.
If you won't declare any variables on the stack, just drop your
declaration of a destructor - it isn't needed. Instead, to prevent
accidental external delete calls, you could declare a class operator new
public and operator delete protected, which shouldn't affect your POD
status. Instead, you could make the Destroy function call FreeAgent()
before delete this.
/**
** \brief Carries a request and any associated parameters.
**/
struct PNPEXPORT IConcurrentOperations::OpRequest abstract : OpMessage
{
...
private:
/**
** \brief Destructor, executes cleanup
**
** Calls FreeAgent to manage reference counting pAgent.
**
** Private visibility prevents declaration on the stack.
**/
~OpRequest()
{
FreeAgent();
}
public:
/**
** \brief Frees resources used by this request
**/
void Destroy( void )
{
delete this;
That is problematic, since your destructor isn't virtual. You can't
destroy an object through a base class pointer unless it has a virtual
destructor.
}
};
/**
** \param Base, should be derived from OpNotification or OpRequest
** and provide a default constructor.
**/
template<typename Base>
struct IConcurrentOperations::BufferedMessage : public Base
{...}
What are you trying to do? We might be able to suggest a workable design.
Tom