CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Nov 2008
    Posts
    26

    Singleton class and static data members of the class type

    Hi : )

    Last night a had a really hard time trying to understand the singleton pattern for a class which has a data member, with the same type as the class itself:

    Code:
    class Singleton
    {
    public:
    
    	void printData() { cout << data << endl;}
    
    private:
    
    	Singleton(): data(0) { /* other work */ }
    	Singleton( const Singleton &);				// never defined
    	Singleton & operator=( const Singleton &);	// never defined
    	~Singleton();
    
    	int data;
    
    	static Singleton singleton;
    
    };
    Ok, so, now I want to be able to use object singleton as a regular object - a want to have access to its public data members from outside the class scope. Let's just say that I prefer to use an object of type Singleton, rather than a pointer to a Singleton object.

    This code, as it is compiles fine, but singleton(the static object) is never created ( i think..)
    I suppose, as any other static data member, singleton must be defined exactly once outside the class body. How do I do that with a private constructor?
    I suppose I should define a public static function that:
    1. creates dynamically an object if there is no object created
    2.returns a reference to it..

    Basically my question is:

    If i define only one constructor that is private, how can I initialize the class static member, which is an object of the same type as the class itself outside the class definition?

    It's all very confusing...
    Last edited by seventhirty; July 23rd, 2009 at 06:27 AM.

  2. #2
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Singleton class and static data members of the class type

    Perhaps it would be easier just to show you a simple example of a singleton. This is my logger that I use in all my games (some stuff removed for simplicity):

    Logger.h:
    Code:
    class Logger
    {
    public:
    	static void Initialise(const boost_path& file_name);
    
    	static Logger& Get();
    
    	void Log(const std::string& str);
    	void Save_Log();
    private:
    	static Logger instance;
    	static bool initialised;
    
    	boost_path file_name;
    	std::vector<std::string> buffer;
    };
    Logger.cpp (LOG is just a #define that is a shorter way to call Logger::Get().Log()):
    Code:
    Logger Logger::instance;
    bool Logger::initialised = false;
    
    void Logger::Initialise(const boost_path& file_name)
    {
        if(!initialised)
        {
    	    instance.file_name = file_name;
    	    instance.time_info = NULL;
    	    instance.raw_time = 0;
    	    initialised = true;
                LOG("Logger initialised.");
        }
        else
        {
            LOG("Warning: Logger already initialised.");
        }
    }
    
    Logger& Logger::Get()
    {
    	if(!initialised)
    	{
                throw std::runtime_error("Logger not initialised.");
    	}
    
    	return instance;
    }
    
    void Logger::Log(const std::string& str)
    {
    	buffer.push_back(str);
    }
    
    void Logger::Save_Log()
    {
    	// Save the log to file_name.
    }
    You can initialise the singleton like so:
    Code:
    Logger::Initialise("folder/file.txt");
    When you're done:
    Code:
    Logger::Get().Save_Log();
    Hope that helps.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  3. #3
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Singleton class and static data members of the class type

    Quote Originally Posted by seventhirty View Post
    This code, as it is compiles fine, but singleton(the static object) is never created ( i think..)
    If you define it in a cpp file, it is created when the program starts up, before main() is executed.
    I suppose, as any other static data member, singleton must be defined exactly once outside the class body. How do I do that with a private constructor?
    Code:
    #include "Singleton.h"
    
    Singleton Singleton::singleton;
    I suppose I should define a public static function that:
    1. creates dynamically an object if there is no object created
    2.returns a reference to it..
    That's a different design for a singleton. It has it's benefits (singleton object is not created if it is never called, multiple singletons can be dependend on each other during initialization), but it is also much harder to implement. A good implementation can be found in the Loki library.
    With the design you have, you just need a static member function that will return a reference to the one-and-only object.
    If i define only one constructor that is private, how can I initialize the class static member, which is an object of the same type as the class itself outside the class definition?
    The static object is defined within the scope of the Singleton class. Therefore, it has access to the private constructor.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  4. #4
    Join Date
    Mar 2009
    Posts
    94

    Re: Singleton class and static data members of the class type

    Quote Originally Posted by seventhirty View Post
    Hi : )

    Code:
    class Singleton
    {
    public:
    
    	void printData() { cout << data << endl;}
    
    private:
    
    	Singleton(): data(0) { /* other work */ }
    	Singleton( const Singleton &);				// never defined
    	Singleton & operator=( const Singleton &);	// never defined
    	~Singleton();
    
    	int data;
    
    	static Singleton singleton;
    
    };
    hmm I dont know, but how can there be any object of type Singleton? I see no way of calling the constructor.

  5. #5
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Singleton class and static data members of the class type

    The static object "singleton" will of course be created; it's within the class namespace, so it has access to the private constructor.

    However, it isn't very useful since it's also private. Typically in the singleton pattern, you'd either make the static instance public so that you can access it as Singleton::singleton, or else you'd write a public static function to get it, such as Singleton::getInstance().

    The function approach is usually preferred since it makes it possible to "silently" change what type of singleton it is in the future without modifying any code that uses it.

  6. #6
    Join Date
    Nov 2008
    Posts
    26

    Re: Singleton class and static data members of the class type

    Thanks for the answers.

    Lindley, if I use the second approach that you mention, the one with the function getInstance, does that mean that everytime the user of the class wants to use some function the class, he/she has to call getInstance() to obtain the static object( like Mybowlcut's logger class)?

    And a design question: when making some application do I have to make every class, of which there is only one object throughout the whole program, a singleton ( cursor, mainMenu, InputSubsystem, Renderer.. all the modules, everything??) I mean, if I do that and use the getInstance() approach, isn't that going to make all the code unclear and complicated??
    Last edited by seventhirty; July 24th, 2009 at 09:47 AM.

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Singleton class and static data members of the class type

    Quote Originally Posted by seventhirty View Post
    Thanks for the answers.

    Lindley, if I use the second approach that you mention, the one with the function getInstance, does that mean that everytime the user of the class wants to use some function the class, he/she has to call getInstance() to obtain the static object( like Mybowlcut's logger class)?
    Well, you can always store the result of getInstance() into a local pointer or reference if you want. Then you don't have to call it so many times.

    And a design question: when making some application do I have to make every class, of which there is only one object throughout the whole program, a singleton ( cursor, mainMenu, InputSubsystem, Renderer.. all the modules, everything??) I mean, if I do that and use the getInstance() approach, isn't that going to make all the code unclear and complicated??
    That's a valid concern----singletons are only a slightly better alternative to global variables, after all.

    I'd say, use a singleton if and only if (a) it logically makes sense for there to be only one of something, (b) you'll need to access that single object from many widely-distributed areas of the program, and (c) passing a pointer to the object around would make it a parameter of just about everything anyway.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured