In my class design 开发者_StackOverflow中文版I ran into the following problem:
class MyData
{
int foo;
};
class AbstraktA
{
public:
virtual void A() = 0;
};
class AbstraktB : public AbstraktA
{
public:
virtual void B() = 0;
};
template<class T>
class ImplA : public AbstraktA
{
public:
void A(){ cout << "ImplA A()"; }
};
class ImplB : public ImplA<MyData>, public AbstraktB
{
public:
void B(){ cout << "ImplB B()"; }
};
void TestAbstrakt()
{
AbstraktB *b = (AbstraktB *) new ImplB;
b->A();
b->B();
};
The problem with the code above is that the compiler will complain that AbstraktA::A() is not defined.
Interface A is shared by multiple objects. But the implementation of A is dependent on the template argument. Interface B is the seen by the outside world, and needs to be abstrakt.
The reason I would like this is that it would allow me to define object C like this: Define the interface C inheriting from abstrakt A. Define the implementation of C using a different datatype for template A.
I hope I'm clear. Is there any way to do this, or do I need to rethink my design?
You have two paths of inheritance from AbstracktA, you implement AbstraktA::A() only in one of them, so the compiler complains.
You probably want to inherit virtually from AbstraktA in both case so that there is only one AbstraktA base object (add virtual
before AbstraktA).
I forgot to add virtual destructors to the base classes. This leads to runtime malloc errors I believe.
AbstraktB *b = new ImplB;
b->A();
b->B();
delete b;
In debug mode, at the delete statement, GCC gives me: malloc: *** error for object 0x60e2c4: pointer being freed was not allocated
I solved this by changing the base classes to:
class AbstraktA
{
public:
virtual ~AbstraktA(){};
virtual void A() = 0;
};
class AbstraktB : virtual public AbstraktA
{
public:
virtual ~AbstraktB(){};
virtual void B() = 0;
};
精彩评论