Page 1 of 1

defining an interface (solved)

Posted: Tue Jun 21, 2011 12:35 am
by short
Hey guys,

I have a non-obvious to me question for anyone. I'm trying to inherit form an abstract base class, here's an example of the scenario I'm currently trying to wrap my head around:

AbstractMemoryPool.h

Code: Select all

#ifndef _ABSTRACTMEMORYPOOL_H_
#define _ABSTRACTMEMORYPOOL_H_

class AbstractMemoryPool
{
public:
	virtual ~AbstractMemoryPool() { int j = 5; };

	virtual void whatevs() = 0;
};

#endif
ParticleMemoryPool.h

Code: Select all

#ifndef _PARTICLEMEMORYPOOL_H_
#define _PARTICLEMEMORYPOOL_H_

#include "AbstractMemoryPool.h"

class ParticleMemoryPool : public AbstractMemoryPool
{
public:
	ParticleMemoryPool(void);
	virtual ~ParticleMemoryPool(void);

	virtual void whatevs();
};
#endif
ParticleMemoryPool.cpp

Code: Select all

#include "ParticleMemoryPool.h"

ParticleMemoryPool::ParticleMemoryPool(void)
{
}

ParticleMemoryPool::~ParticleMemoryPool(void)
{
}

void ParticleMemoryPool::whatevs()
{
}
As you can see I provided no implementation for abstractMemoryPool (no .cpp file), just the .h (interface) file.

However noting the virtual destructor

Code: Select all

virtual ~AbstractMemoryPool() { int j = 5; };
This causes no linker problems. However replacing the destructors definition with either of

This

Code: Select all

virtual ~AbstractMemoryPool();
and

Code: Select all

virtual ~AbstractMemoryPool() = 0;
ends up in linker issues bitching about the missing implementation of AbstractMemoryPool::~AbstractMemoryPool(void).

Of course theres no implementation of the destructor, I just want to define an interface in AbstractMemoryPool.h.

Why if I do not provide an inline body for the virtual destructor of AbstractMemoryPool does the linker bitch?

I explicitely override the virtual destructor in ParticleMemoryPool.cpp

Re: defining an interface

Posted: Tue Jun 21, 2011 2:54 am
by Aleios
Simply because the Base class also needs to be deconstructed, this means that it needs at least some implementation. Basically the destructor must be able to be called. I hope i answered the question, there is probably more too it than what i said, but i always think back to just define it or leave it out.

EDIT: ok so i re-read this back to me and i confused myself.

Basically the compiler will (always?) call the destructor for you, so if it has nothing to call it will bitch, i believe that is why the linker will go mad.

Re: defining an interface

Posted: Tue Jun 21, 2011 9:04 am
by Falco Girgis
That's kind of just the way abstract classes work.

Constructors/Destructors work differently than other member functions. They are executed (in the case of the destructor), from the bottom up, like popping methods off of a destructor stack.

Because of this, you can't declare a destructor without a body:

Code: Select all

virtual ~AbstractMemoryPool() = 0;
There MUST be an implementation of a destructor at every stage of the tree. It is even called at the abstract base.

Ideally, I'm sure that what you WANT to do is say "use the default, compiler-supplied destructor, but also force the inheriting class to have to implement it." Unfortunately, there's no way to syntactically represent that in C++. Declaring the destructor virtual or purely virtual is also simultaneously declaring a destructor... so you have to implement it.

Re: defining an interface

Posted: Tue Jun 21, 2011 11:00 am
by short
Thank you good sirs. :bow: