I have an abstract class:
class A
{
public:
bool loaded_;
virtual int load() = 0;
}
And several derived classes :
class B:public A
{
public:
int load();
static B& instance();
}
class C:public A
{
public:
int load();
static C& instance();
}
The fact is that the code inside ::instance() methods is the same for each class :
static B& B::i开发者_如何学JAVAnstance()
{
static B instance_;
if (!instance_.loaded_)
{
instance_.load();
instance_.loaded_=true;
}
return instance_;
}
static C& C::instance()
{
static C instance_;
if (!instance_.loaded_)
{
instance_.load();
instance_.loaded_=true;
}
return instance_;
}
I would like to factorize this ::instance method, but given that it uses the virtual method ::load, i cannot define it in the class A. Theoretically, i know it's weird since the class A should have 0 instance and B,C should have 1 instance but it also makes sense that this code should be factorized.
How would you solve that problem ?
You could make instance()
a free function template:
template<class T>
T& instance()
{
static T instance_;
if (!instance_.loaded_)
{
instance_.load();
instance_.loaded_=true;
}
return instance_;
}
Then you can use it like this:
instance<B>().do_stuff()
This is a common usage of the CRTP, define the function that creates the instance in the template and then instantiate it in each type:
struct A {
virtual ~A() {} // don't forget to make your destructor virtual!
virtual void load() = 0;
};
template <typename T>
struct instance_provider {
static T& instance() { /* implementation */ }
};
struct B : A, instance_provider<B> {
virtual void load();
};
struct C : A, instance_provider<C> {
virtual void load();
};
精彩评论