Suppose we have a function that does this
if class is foo, use a new implementation
else use an old implementation
There are many ways to achieve this. The naive way is as shown below.
if (instance.type() == "foo") {
instance.new_impl();
} else {
instance.old_impl();
}
Another way is to use a runtime polymorphism as shown below.
class foobar_base {
public:
virtual ~foobar_base() {}
virtual void impl() = 0;
}
class foo : public foobar_base {
public:
virtual ~foo() {}
void impl() {
cout << "New implementation" << endl;
}
};
class bar : public foobar_base {
public:
virtual ~bar() {}
void impl() {
cout << "Old implementation" << endl;
}
}
void do_something(const foobar_base& fb) {
fb.impl();
}
If we need to avoid any runtime type check and use a compile-time type check, we can achieve it by leveraging on the C++ templates and use C++ traits to store the type information as shown on the example below.
#include <iostream>
using namespace std;
template<typename T>
struct impl_traits {
static const bool value = false;
};
template<typename T>
void do_something() {
if (impl_traits<T>::value) {
T::new_impl();
} else {
T::old_impl();
}
};
class foo {
public:
static void old_impl() {
cout << "[foo] Old implementation" << endl;
}
static void new_impl() {
cout << "[foo] New implementation" << endl;
}
};
class bar {
public:
static void old_impl() {
cout << "[bar] Old implementation" << endl;
}
static void new_impl() {
cout << "[bar] New implementation" << endl;
}
};
template<>
struct impl_traits<foo> {
static const bool value = true;
};
int main() {
do_something<foo>();
do_something<bar>();
return 0;
}
The output is
[foo] New implementation
[bar] Old implementation
No comments:
Post a Comment