Re: Repository of all objects of a certain type
James Kanze wrote:
Would something like the following work here:
template< typename ObjType, typename KeyType >
class ContainerSupport
{
private:
static sorted_vector_p<ObjType, KeyType> RP_Index;
public:
// Factory:
// Fetches an existing instance or creates a new one for the
key K.
static my_intrusive_ptr<ObjType> GetByKey(const K& key);
// Fetches an existing instance or return NULL.
static my_intrusive_ptr<ObjType> FindByKey(const K& key)
{ return RP_Index.find(key); }
} ;
then:
class MyObject : public ContainerSupport< MyObject, MyKey >
// ...
{
// ...
} ;
As long as the only things in the base class template which
depend on the template parameter are static members or friends,
I think it should work.
Well, the only disadvantage I see is that the factory of ObjType (or the
constructor) must be public. This is a bit dangerous with respect to
data integrity.
> You might have to use the compilation
firewall idiom or the singleton pattern for the RP_Index, but I
don't think it should be necessary. Static data members of a
template should only be instantiated when and where used;
It should be sufficient when the statics are linked as weak symbols when
the template class is instantiated for some certain parameters from a
C++ file. But you are right. Strictly speaking there is a cyclic
dependency to the derived class. I have to check this since the compiler
is quite old. But I think I already used something like that.
I just tested the following:
class MyObject : public ContainerSupport<MyObject, MyKey>
{ friend class ContainerSupport<MyObject, MyKey>;
....
It works as far as I can see and the constructor of MyObject is private.
I wonder a bit since ContainerSupport<MyObject, MyKey> is not yet a
friend of MyObject when the template is instantiated. But at least the
17 year old IBM compiler and gcc 3.3.5 ate it. Maybe because of the same
reason as the above dependency.
Pretty useful pattern.
Marcel