Reputation: 410
I'm trying to write a Testbench that can test different implementations of an Interface. Coming from Java I would love to just specify an Interface, create some Classes that implement it and write a class Testbench<T extends MyInterface>
Transforming this approach to C++ gives something like:
// The Interface
class Animal {
public:
Animal(int age) {};
virtual ~Animal() {};
virtual void Say();
};
// An Implementor
class Cow : Animal {
private:
int age;
public:
Cow(int age) : Animal(age) {
this.age = age;
};
void Say() {
std::cout << "I'm an " << age << " year old Cow" << std::endl;
}
}
Next I define the templated class that can test different Animals:
template<> void AnimalTestbench<class T> {
static void TestSay();
}
But when I try to implement the TestSay method, it gives me "Allocation of incomplete type T"
template<> void AnimalTestbench<class T>::TestSay() {
T *animal = new T(5);
animal->Say();
}
Of course I didn't specify that T should be an Animal, this is my first question. The latter is: why does this code fail?
I've heard that Templates are a fancy way for Macros that know about types, but if it's a Macro in a way, then the compiler should first replace T with my (complete) Type which he should be able to allocate and instantiate.
Upvotes: 1
Views: 170
Reputation: 970
The correct syntax for template classes is:
template<typename T> void AnimalTestbench {
static void TestSay();
}
And the method:
template<typename T> void AnimalTestbench<T>::TestSay() {
T *animal = new T(5);
animal->Say();
}
Upvotes: 0
Reputation: 41110
There are a number of issues with your code:
Animal
class should declare Say
as pure virtualAnimal
class uses this.
instead of this->
Cow
class does not derive publicly from Animal
AnimalTestbench
class does not use templates correctly, template<>
defines a specialization, which is not what you wantT *animal = new T(5);
is a memory leak, because a delete
doesn't follow.
Fixed Animal
class:
class Animal {
public:
Animal(int) {};
virtual ~Animal() {};
virtual void Say() = 0;
};
Fixed Cow
class:
class Cow : public Animal {
private:
int age;
public:
Cow(int age) : Animal(age) {
this->age = age;
};
void Say() override{
std::cout << "I'm an " << age << " year old Cow" << std::endl;
}
};
Fixed AnimalTestbench
(we don't need to separate the impl of TestSay
from the declaration, but I'm following your approach:
template<class T>
struct AnimalTestbench
{
static void TestSay();
};
template<class T>
void AnimalTestbench<T>::TestSay() {
T animal(5);
Animal *animal_base = &animal;
animal_base->Say();
}
Usage:
int main()
{
AnimalTestbench<Cow>::TestSay();
}
TestSay
could be a standalone templated function, but I presume there are other virtual functions you wish to test and it's convenient to put them all in a single test class.
Upvotes: 4