I recently found a case where it was easier to specialize a template instead of real inheritance. Derived classes simply had to implement a pure virtual function and did not have their own members. It was something like:
#include <iostream>
class Interface {
public:
virtual void calculate() = 0;
virtual float getResult() = 0;
};
class Base : public Interface {
float result;
public:
Base() : result(1) {};
virtual ~Base() {};
virtual void calculate();
virtual float getValue() = 0;
float getResult() { return result; }
};
class DerivedA : public Base {
public:
DerivedA() : Base() {};
~DerivedA() {};
float getValue();
};
class DerivedB : public Base {
public:
DerivedB() : Base() {};
~DerivedB() {};
float getValue();
};
void Base::calculate() {
for (int i = 0; i < 10; i++)
result += getValue();
}
float DerivedA::getValue() {
return 1;
}
float DerivedB::getValue() {
return 1.1;
}
int main() {
Interface * a = new DerivedA();
a->calculate();
Interface * b = new DerivedB();
b->calculate();
std::cout << "Result A: " << a->getResult() << std::endl;
std::cout << "Result B: " << b->getResult() << std::endl;
delete a;
delete b;
}
This can be written in the form of specialized templates:
#include <iostream>
class Interface {
public:
virtual void calculate() = 0;
virtual float getResult() = 0;
};
template<typename T>
class Base : public Interface {
float result;
public:
Base() : result(1) {};
void calculate();
float getValue();
float getResult() { return result; };
};
typedef Base<int> DerivedA;
typedef Base<float> DerivedB;
template<typename T>
void Base<T>::calculate() {
for (int i = 0; i < 10; i++)
result += getValue();
}
template<typename T>
float Base<T>::getValue() {
return 0;
}
template<>
float Base<int>::getValue() {
return 1;
}
template<>
float Base<float>::getValue() {
return 1.1;
}
int main() {
Interface * a = new DerivedA();
a->calculate();
Interface * b = new DerivedB();
b->calculate();
std::cout << "Result A: " << a->getResult() << std::endl;
std::cout << "Result B: " << b->getResult() << std::endl;
delete a;
delete b;
}
Both examples give the same results, I believe that the second one is faster, since no virtual tables need to be evaluated (the getValue () methods can even be built into the second case).
, : ? , ? ? , , . , , - ?
Btw: ?