What is this article about?This article is about a nice way to manage all kinds of data structures in an easy way. I will discuss how to make a templated singleton manager. For those people who do not know what the first two words mean, there are a lot of nice tutorials about these on the internet. And it is recommended to first understand what templates and singletons are in order to fully understand this article. I will not discuss them here because they are programming concepts which should be familiar to the serious programmer. PurposeThe purpose of this article is to learn an approach to program stable managers which provide basic functions that never need to be rewritten. So what does that mean for you? You could use this approach for managing your own data structures and avoid wasting time and effort repeatedly writing the same type of code. You could use this approach for managing all kinds of data structures, such as images, textures, sounds, meshes, and so on. How to do a 'normal' template managerFirst I will explain how you can create a 'normal' template manager, because it will be much easier to understand the singleton version later. I will start with a piece of code and then explain the relevant portions: template <class T, int n> class TManager { public: TManager(void); ~TManager(void); int Add(const T* p_T); int Delete(const T* p_T); int Delete(int index); int DeleteAll(); T* Get(int index); T* Get(const T* p_T); Int GetCount(); int GetError(); char *GetErrorString(); protected: int error; T* p_T[n]; }; (Note that this is only the interface. For information on implementation details, see the attached code files.) Well that really is everything there is to the interface. Most functions perform rather obvious operations, although the last three functions might seem strange. These functions really aren't required but I used them anyway. The GetCount() function returns the maximum number of objects that can be managed by this class. The GetError() function returns an error code if one of the previously called functions failed. Normally I just give functions two types of return values - one indicates success and one indicates failure. On failure I then call the GetError() function to retrieve the error. Note that this is much the same way OpenGL and other standard APIs work. The GetErrorString() function returns an appropriate description for the error (which might come in handy for debugging or logging an application). The key to understanding what is done here is to see that this template 'generates' code, the code that you specified for the functions, when you make a class inherit from it. Note that the 'T' stands for the class type you want to use and that 'n' stands for the number of objects you want to be able to manage at most. When looking at the source code (attached to this document) the smart people will see that I do something rather suspicious. In some methods I compare or assign a class using standard '==' and '=' operators. Therefore, it is important that you overload these operators for the classes you want to use with the manager. But since overloading those operators is very easy, I will let that be an exercise for you. |
|