Reputation: 2605
So I have a class template Foo
:
template <typename T>
class Foo
{
public:
Foo();
~Foo();
//...
};
I have two derived classes from the Foo class:
class FooDerived1 : public Foo<int>
{
public:
FooDerived1 ();
~FooDerived1 ();
};
class FooDerived2 : public Foo<double>
{
public:
FooDerived2 ();
~FooDerived2 ();
};
But now I saw that the class template was being used on a abstract class IBar
like this:
class Foo;
class IBar
{
public:
virtual void placeFoo(Foo& foo) = 0; //error
virtual void removeFoo(Foo& foo) = 0;
};
I know I cannot use templates classes in abstract virtual classes.
But..in a case like this, what should I do?
I really need the IBar abstract class like this...
Forget the usage of template classes?
Upvotes: 1
Views: 102
Reputation: 12058
If you need common behaviour, create base class for all instances of Foo<>
:
class FooBase
{
//common interface and data
};
template <class T>
class Foo : public FooBase
{
};
And then:
class FooBase;
class IBar
{
public:
virtual void placeFoo(FooBase& foo) = 0; //ok
virtual void removeFoo(FooBase& foo) = 0;
};
The thing is, that you try to mix templates (compile time) and dynamic polymorphism (runtime), which can be problematic (is it what you meant by "I know I cannot use templates classes in abstract virtual classes"?).
Why not stick to using templates?
class IBar
{
public:
template <class T>
void placeFoo(Foo<T>& foo);
template <class T>
void removeFoo(Foo<T>& foo);
};
or:
template <class T>
class IBar
{
public:
void placeFoo(Foo<T>& foo);
void removeFoo(Foo<T>& foo);
};
Upvotes: 1
Reputation: 27528
Option 1: Make IBar
itself a template class.
template <class T>
class Foo;
template <class T>
class IBar
{
public:
virtual void placeFoo(Foo<T>& foo) = 0;
virtual void removeFoo(Foo<T>& foo) = 0;
};
Option 2: Make all Foo<T>
derive from a common, non-generic FooBase
.
class FooBase
{
// ...
};
template <typename T>
class Foo : public FooBase
{
public:
Foo();
~Foo();
//...
};
// ...
class FooBase;
class IBar
{
public:
virtual void placeFoo(FooBase& foo) = 0;
virtual void removeFoo(FooBase& foo) = 0;
};
The viability of both solutions depends on how much you actually depend on the T
type. But that's what you should expect when you mix virtual functions with templates. With option 1, you do not have a common interface type anymore; with option 2, FooBase
cannot provide any member function with a T
-dependent argument.
By the way, don't forget about virtual destructors in your real code.
Upvotes: 1