template <class Type>
class Manager {
public:
//Some General functions for a manager... something along this:
AddItem(Type);
RemoveItem(Type);
RemoveAll();
Type GetItem();
privat:
//here comes a container of some sort
};
But soon I realized that that won't work. We want to be able to choose what type of container we want our manager to use. But hey, now I realized that the AddItem will be different for some containers, eg. adding an item to a std::map is different from adding an item to a std::list.
Well, so what I though about was applying some kind of Traits or some kind of Container Policy that will take care of the common functions for a given container.
Ok, so my next design was something along this:
Manager.h
template <class ContainerPolicy>
class Manager : public ContainerPolicy {
public:
Manager();
~Manager();
private:
};
Now when creating a Manager I will have to choose a ContainerPolicy class to derive from, the policy that will take care of the desired functions. (AddItem, RemoveItem...)
ContainerPolicy.h
template <
class Type,
void (std::list::*pInsertFn)(const Type& obj) = &std::list::push_back
>
struct ListContainer {
protected:
std::list<Type> m_Container;
public:
void AddItem(const Type& obj) {
(m_Container.*pInsertFn)(obj);
}
void RemoveItem(const Type& obj) {
}
int RemoveAll() {
m_Container.clear();
return m_Container.empty();
}
Type& GetItem(int nPos) {
for(LI iterList = m_Container.begin(); iterList != m_Container.end(); ++iterList) {
if(nPos == 0) return *iterList;
}
}
typedef class std::list<Type>::const_iterator LI;
};
The ListContainer will take A type and a functionpointer:
ListContainer<int, /*Pointer to std container member function*/> LI_CONTAINER_1; //but since we have a default function given, this will be enough: ListContainer<char*> LI_CONTAINER_2;The problem I was having was the Member function pointer, but we'll get to that later... oh well, the ListContainer alone isn't much to cheer about. But together with the Manager class that would be not so bad. Think about this:
Manager<ListContainer<int> > MyIntManager; /*This will create a Manager that uses a list as a container and operates on int's only. So Now we can use this: MyIntManager.AddItem(5); MyIntManager.AddItem(10); MyIntManager.AddItem(2); MyIntManager.RemoveItem(2); //removes the second item in the list.. the resulting list will contain the following 5 2 */Well, you may say this is exactly what the List container does! And yes, that is exactly the same as the pure list functions do... But hey, as I stated I use many managers of similar functionalitys ... so to create a new Manager all I have to do is:
class MyNewManager : public Manager<ListContainer<int> >{
};
/*Now whenever I would want to use my Manager class, of course to derive from I would do like this:*/
class CImageManager : public Manager<ListContainer<CImage*> > {
}
/*And hey... now I got a CImageManager that can do the following:
AddItem, RemoveItem, RemoveAll ...*/
And I don't need to revrite the code for it, nice huh
Ok, back to the problem I had about the Pointer to member function. The pointer to member function looked like this:
template < class Type, /* the pointer to member function */ void (std::list::*pInsertFn)(const Type& obj) = &std::list::push_back >It is supposed to point to the std::list:
template < class Type, /* the pointer to member function */ void (std::list<Type>::*pInsertFn)(const Type& obj) = &std::list<Type>::push_back >I had forgotten to add the Type to the list... So the working code of: ContainerPolicy.h
template <
class Type,
/* the pointer to member function */ void (std::list<Type>::*pInsertFn)(const Type& obj) = &std::list<Type>::push_back
>
struct ListContainer {
protected:
std::list<Type> m_Container;
public:
void AddItem(const Type& obj) {
(m_Container.*pInsertFn)(obj);
}
void RemoveItem(const Type& obj) {
}
int RemoveAll() {
m_Container.clear();
return m_Container.empty();
}
Type& GetItem(int nPos) {
for(LI iterList = m_Container.begin(); iterList != m_Container.end(); ++iterList) {
if(nPos == 0) return *iterList;
}
}
typedef class std::list<Type>::const_iterator LI;
};
The Second priblem was that I had :
typedef std::list