Sign in to follow this  
webwraith

Singleton class in a strop

Recommended Posts

Right, so I wrote a singleton template class, with the idea that I could derive singleton classes from it. Here is the singleton code;
#ifndef SINGLETON_H
#define SINGLETON_H

#include <iostream>

template < class Type >
class DesignPattern::Singleton
{
	public:

		Type* const GetReference()
		{
		        if(Singleton<Type>::ref == NULL)
		        {
                                Singleton<Type>::ref = new Type;
                                Singleton<Type>::ref_count = 0;
		        }
                        Singleton<Type>::ref_count++;
                        return Singleton<Type>::ref;
		}

		void ReleaseReference()
		{
		        Singleton<Type>::ref_count--;
		        if(Singleton<Type>::ref_count==0)
		        {
		                delete Singleton<Type>::ref;
		        }
		        Singleton<Type>::ref = NULL;
		}

		size_t GetNumReferences()
		{
		        return ref_count;
		}
	protected:
		size_t ref_count;
		Type* ref;
	private:

};


#endif // SINGLETON_H
Now, the problem comes when I try to create an object of a derived class. My compiler (MinGW) tells me that my class' type is incomplete. The class in question(shortened for brevity);
#ifndef CANVAS_H
#define CANVAS_H

#ifndef WINDOW_HANDLE
        #define WINDOW_HANDLE int
#endif
#ifndef STYLE
        #define STYLE unsigned int
#endif

#include "DesignPatterns.h"
#include <string>

class System::Window: public DesignPattern::Singleton<System::Window>
{
        public:
                ...

        protected:
                friend class DesignPattern::Singleton<System::Window>;


                Window();
                ~Window();

                ...
};

#endif // CANVAS_H

Now, does anyone have any idea what I'm doing wrong? I would be very grateful for any light shone on this matter

Share this post


Link to post
Share on other sites
Quote:
Original post by webwraith
Right, so I wrote a singleton template class, with the idea that I could derive singleton classes from it.

Oh my god, you want several singleton classes? Isn't one bad enough already?

Seriously, why do you need so many singletons?

Share this post


Link to post
Share on other sites
What I meant by that was, I would have a generic singleton class, then any other class that I wanted to be a singleton (say, my input and window classes), I would just derive from the Singleton base-class.

Share this post


Link to post
Share on other sites
Hm, shouldn't ref and ref_count be static?

If they are, be sure to define them once(!) in a .cpp file:

Window * Singleton<Window>::ref = 0;
size_t Singleton<Window>::ref_count = 0;


(I hope it's correct, I haven't done C++ in a loooong time)

Regards,
Andre

Share this post


Link to post
Share on other sites
OK, so I've tried adjusting for static reference and reference counter, but I'm still coming up with the following error;

E:\Programming\Projects\Core Engine System\System.h, line 45,error: field `m_window' has incomplete type


This is where the object of type "Window" exists as a member of the "System" class.

And yes, System is a class, rather than a namespace. This was done to try and make the user experience simpler by having any startup that needs doing (i.e.; any Init()-style functions) hidden from the user. They just have to get a reference to the System class, then use the System object to get references to other objects (in my case, Window, Input, File, Thread, etc.)

[Edited by - webwraith on August 17, 2008 3:24:56 PM]

Share this post


Link to post
Share on other sites
Quote:
E:\Programming\Projects\Core Engine System\System.h, line 45,error: field `m_window' has incomplete type


That error message probably means that you've forward declared whatever type 'm_window' is but haven't given a full definition - it's impossible to tell exactly what's wrong because you haven't given us enough code.

Quote:
Now, does anyone have any idea what I'm doing wrong?

You're trying to create a generic implementation of an anti=pattern?

Share this post


Link to post
Share on other sites
Why are you deriving from your singleton template class? Why not simply use the template class for any type you need it for (assuming you made the singleton functions and contained instance static):

class Input
{
// Fancy input handling goes here
};

Singleton<Input>::GetInstance();

This also means that your Input class is not forced to be a singleton. Such flexibility may come in handy.

Personally though, I'd just create a single instance of those classes and be done with it: you get a single instance without the limitation of only being able to create one, while also retaining full control over accessibility - a singleton is essentially a global after all. Do you really have a compelling reason to use the singleton pattern?

Share this post


Link to post
Share on other sites
Quote:
Original post by webwraith
What I meant by that was, I would have a generic singleton class, then any other class that I wanted to be a singleton (say, my input and window classes), I would just derive from the Singleton base-class.


The point is, "wanting" a singleton shouldn't be common enough to justify the effort. Even if it turns out to be one per project, the amount of effort you can possibly save yourself this way is minimal, and it comes at the expense of promoting the possibility of using a singleton for something where it (a) isn't actually appropriate and (b) might not otherwise come to mind.

Share this post


Link to post
Share on other sites
Quote:
Original post by Captain P
class Input
{
// Fancy input handling goes here
};

Singleton<Input>::GetInstance();

This also means that your Input class is not forced to be a singleton. Such flexibility may come in handy.

Wwwwwow. I don't think I've ever seen such a concise and nuanced critique of How People Tend To Use Singletons. That was awesome.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Wwwwwow. I don't think I've ever seen such a concise and nuanced critique of How People Tend To Use Singletons. That was awesome.



You made my day :-)

"My app uses a bunch of Input instances and a Singleton instance of Input"

Reminds me of "You're all individuals. You're all different" - "I'm not!"

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this