Thread: Still on the subject of Singletons (their usage)

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    Still on the subject of Singletons (their usage)

    Never thought I'd ask this. Since most texts about the singleton pattern focus on its implementation, it hardly occurred to me that I would be facing dilemas concerning their actual usage.

    GameMap is a GoF Singleton returning a reference through getInstance(). The problem is that I'm really not sure what to do with its copy constructor and assignment operator.

    My first thought was to explicitly declare them in order to make it clear to users of the class they can use them. GameMap implements a vector of hexagons and is meant to be used in various contexts by other objects and routines.

    Because of this, I believe it is more practical to write:

    GameMap myMap = GameMap::getInstance();

    Than it is to make copy-control private and have to write something like the following everytime I need to access the container's contents interface:

    GameMap::getInstance().Hexagon(16, 7).hasRoad()

    At best I can simplify a bit by renaming getInstance() to Map(), for instance. But still feels awkward to rely on a temporary all the time.

    I see too much singleton implementations moving copy-control to the private portion of the class definition. So, i'm a little shaky about not doing it. Should I?
    Last edited by Mario F.; 07-23-2007 at 08:04 AM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  2. #2
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    There's no inherent reason you should make a singleton un-copyable. It's just another object, which happens to be global.

    That said... why wouldn't you be passing around a GameMap * instead of copying it?
    Last edited by QuestionC; 07-23-2007 at 08:39 AM.
    Callou collei we'll code the way
    Of prime numbers and pings!

  3. #3
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    perhaps you could pass around a GameMap& instead. If you want a singleton, then you certainly don't want more than one copy floating around your program. If your program requires more than one copy, then a singleton is a bad choice.

    Incidentally, there's no reason why getInstance() has to be a member function. you could just as easily write getInstance as a standalone friend function.
    Last edited by Bench82; 07-23-2007 at 12:01 PM.

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    At best I can simplify a bit by renaming getInstance() to Map(), for instance. But still feels awkward to rely on a temporary all the time.
    getInstance() doesn't built a temp. It provides a reference to a global object. Once constructed with the first call to instance() that object is always the same over time.

    If you want to have a single resource than use singleton and make copy-ctor private.
    If you want to have a fixed number > 1 of a type of resources than you could have a look at "multiple"/ "borg" pattern.

  5. #5
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by QuestionC View Post
    That said... why wouldn't you be passing around a GameMap * instead of copying it?
    Just an overlook. getInstance() does return a reference. The text should read instead:

    GameMap &myMap = GameMap::getInstance();

    Quote Originally Posted by QuestionC View Post
    There's no inherent reason you should make a singleton un-copyable. It's just another object, which happens to be global.
    Most excellent. Thanks.

    Quote Originally Posted by bench82
    Incidentally, there's no reason why getInstance() has to be a member function. you could just as easily write getInstance as a standalone friend function.
    Hmm... even with it being static?
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  6. #6
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Quote Originally Posted by Mario F. View Post
    Just an overlook. getInstance() does return a reference. The text should read instead:

    GameMap &myMap = GameMap::getInstance();
    Yea... but you don't need the copy constructor to do that.

    Singleton issues aside, would it make sense to make the GameMap copy constructor private anyhow? I am guessing that its a very expensive object to copy.
    Callou collei we'll code the way
    Of prime numbers and pings!

  7. #7
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Quote Originally Posted by Mario F. View Post
    Because of this, I believe it is more practical to write:

    GameMap & myMap = GameMap::getInstance();

    Than it is to make copy-control private and have to write something like the following everytime I need to access the container's contents interface:

    GameMap::getInstance().Hexagon(16, 7).hasRoad()
    Also... note that there are efficiency reasons for using the former as opposed to the latter. Every call to getInstance() will at least perform an extra comparison, and probably perform a mutex lock as well.
    Callou collei we'll code the way
    Of prime numbers and pings!

  8. #8
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    Quote Originally Posted by Mario F. View Post
    Hmm... even with it being static?
    Friend functions can access any members in the class (Including private constructors...), so, one of (probably several) possible ways to do this is to create the static singleton object inside the friend function.

    Code:
    class MySingleton
    {
       MySingleton();
       MySingleton(MySingleton&);
    public
       friend MySingleton& getInstance();
    };
    
    MySingleton& getInstance()
    {
       static MySingleton* the_singleton = new MySingleton;
       return *the_singleton;
    }
    (untested)


    The slight disadvantage of this, is that the_singleton's destructor will never be called. But this shouldn't normally be a problem, as long as you don't need any fancy stuff to happen in the destructor.
    Last edited by Bench82; 07-24-2007 at 04:22 PM.

  9. #9
    Registered User
    Join Date
    May 2007
    Posts
    88
    Quote Originally Posted by QuestionC View Post
    There's no inherent reason you should make a singleton un-copyable. It's just another object, which happens to be global.
    A singleton is a class of which there can and should only be one instance at any given time. If you're wanting to copy the object, then you shouldn't be using the singleton pattern in the first place.

    The right way to do this, if it is truly necessary that there is only one instance of the GameMap object, is to have the getInstance() method return a pointer to the instance and not a reference. Then, you could do this:

    Code:
    GameMap* myMap = GameMap::getInstance()
    myMap->whatever();
    This way, you don't copy the singleton (thus negating the purpose of the singleton pattern in the first place), and you still end up with basically the same syntactic sugar.

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> have the getInstance() method return a pointer to the instance and not a reference.
    What's the difference between a pointer and a reference in that situation? Did you mean "return a pointer and not an object"?

  11. #11
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    returning a pointer does on some monday morning lead some programmer to try to delete the singleton object. returning a reference doesn't lead them into such a temptation.

    QuestionC: For what reason do you want to have a copyable singleton? A singleton models single resources, the realtime clock or a database connection for example. while single resources are not copyable, a singleton shouldn't be, too. Have you an example for a design where a copyable singleton is needed?

  12. #12
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by pheres View Post
    returning a pointer does on some monday morning lead some programmer to try to delete the singleton object. returning a reference doesn't lead them into such a temptation.
    Absolutely. There's also the general advise, when given the choice, choose references over pointers; The validity of which I see no reason to question on this case. As Daved pointed out, there's no significant difference. If there's no difference, reference is the way to go.

    Quote Originally Posted by QuestionC
    Singleton issues aside, would it make sense to make the GameMap copy constructor private anyhow? I am guessing that its a very expensive object to copy.
    That is indeed my main dilema. The object is indeed expensive to copy. Not wanting to bore you with the details, just to mention that the GameMap when fully initialized implements a vector of 14060 MapHex objects from a database query.

    The problem here is that relying on temporary usage of GameMap is awkward - and does incur in a slightly downgrade in performance from repeated calls to getInstance() as you pointed out. So, making the copy constructor and the assignment operators private forces me into a syntax that is both awkward and slower (although, I must say, performance issues are not a concern and should never be).

    On the other hand, I find that making the copy constructor private and keeping with the compiler generated assignment operator is... ugly. I either need both or none. At least users of the class expect that. From my understanding the copy constructor and assignment constructor incur in the same overhead. If the user creates a reference to the singleton (as opposed to a non reference object) with either one of them, the overhead is... what?... zero?

    It was because I was seeing so many singleton examples making copy-control private that I started to have doubts about having my own public. I could eventually follow Bench82 advise and make getInstance() an helper function thus, simplifying the syntax for a private copy-control implementation... however, it would complicate the logic and code readability, I reckon.
    Last edited by Mario F.; 07-25-2007 at 09:36 AM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    What does copying have to do with references? Since you're using references, copying should never occur. The right thing to do is to make the copy constructor and assignment operator private, then fix all compiler errors that occur because somewhere some piece of code tries to copy the object returned by getInstance().

    It's called "single"ton for a reason.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    I know. I apologize. Been wasting you folks time. Last night it just popped on my mind that if I'm creating a reference, of course I wouldn't be using the copy constructor. Silly me.

    QuestionC mentioned it on a previous post and I didn't do the math. My bad.

    Private they are now and everything is ok. Thanks everyone.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reduce CPU usage
    By patrick22 in forum Windows Programming
    Replies: 9
    Last Post: 07-10-2009, 02:13 PM
  2. Net cpu usage of pthreads?!
    By mynickmynick in forum C++ Programming
    Replies: 15
    Last Post: 09-26-2008, 07:59 AM
  3. Calculating CPU Usage
    By vitaliy in forum Linux Programming
    Replies: 3
    Last Post: 08-21-2005, 09:38 AM
  4. Win2K Limiting CPU Usage?
    By drdroid in forum Tech Board
    Replies: 4
    Last Post: 03-31-2004, 02:08 PM
  5. Parsing e-mail headers for subject field
    By SMurf in forum Windows Programming
    Replies: 2
    Last Post: 04-11-2002, 02:57 AM