Thread: Should I make this a singleton?

  1. #1
    In the Land of Diddly-Doo g4j31a5's Avatar
    Join Date
    Jul 2006
    Posts
    476

    Should I make this a singleton?

    Hi, been a while since my last post. Been busy with a project.

    Okay here's the question. I have an object that should only have an instance. But the object should not be created with the default constructor. It's because to create the object, the programmer should define the parameters of the creation of the object. I was thinking of doing this:

    Code:
    clase CObject
    {
        public:
            CObject * getInstance(param A, param B, param C, ...); //To get the instance of the object and create it if it wasn't already created
            methodA();
        private:
            static CObject * mTheObject;
            CObject(param A, param B, param C,...);
    }
    
    CObject * CObject::getInstance(param A, param B, param C, ...)
    {
      if (mTheObject==0)
              mTheObject=new CObject(param A, param B, param C, ...);
      return mTheObject;
    }
    With this code, e.g., if I wanted to call method a, should call it with:
    Code:
    CObject::getInstance(param A, param B, param C, ...)->methodA();
    But getting the instance with parameters that just only needed once to create the object is not too efficient so I was hesitant to implement it. I could just make it a generic one and just make sure I didn't make it more than once throughout my code. But I just wanted to see a different approach in this. Any idea?

    Thanks in advance.
    ERROR: Brain not found. Please insert a new brain!

    “Do nothing which is of no use.” - Miyamoto Musashi.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    With it still being a singleton, you can have a set parameters function to set the parameters. Then either create the object then or save them for when you need them. If you are creating the object then (because you know the program will always need it and there's no need to wait), then just make a Create function.

  3. #3
    In the Land of Diddly-Doo g4j31a5's Avatar
    Join Date
    Jul 2006
    Posts
    476
    Sorry for the delay. Been busy with a bug.

    Anyway, so I should hard code the initialization variables into the singleton itself? What if I wanted the user to set the variables on run time?
    ERROR: Brain not found. Please insert a new brain!

    “Do nothing which is of no use.” - Miyamoto Musashi.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    No, make a function that will initialize the object and create it with new. Then, make sure you call this function early in the program, before you try to use the singleton. Pass the user input to the function at that time, and that function calls the constructor with the data.

    You could have the initialization variables saved in the class itself, but that would only make sense if you wanted to optimize it by not instantiating the class until it is needed.

    Either way, the getInstance() method can just return the pointer, and if it hasn't been created then throw some sort of error. It won't need to take any parameters.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Basically, having getInstance() take parameters is a bad idea because this means that every place that wants to use the singleton either needs access to the original parameters or must create fake parameters and rely on the fact that, after first creating the object, getInstance simply discards them. This is unintuitive, inefficient and fragile.
    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

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    I agree with CornedBee on this one. The thing with singletons is that, by design, you will normally know the state in which the object should initially be created.

    The approach I would use (if, hypothetically, I wanted to do what you are trying to do) would be something like this;
    Code:
    clase CObject
    {
        public:
            static CObject * getInstance(); //To get the instance of the object and create it if it wasn't already created
    
            void SetParameters(param A, param B);
            void methodA();
        private:
            static CObject * mTheObject;
    }
    
    CObject * CObject::getInstance()
    {
      if (mTheObject==0)
              mTheObject=new CObject;
      return mTheObject;
    }
    
    void CObject::SetParameters(param A, param B)
    {
         // set parameters for current instance
    }
    If you really must have the parameters as arguments to a constructor (which I would query the value of), then do this;
    Code:
    clase CObject
    {
        public:
            static CObject * getInstance(); //To get the instance of the object and create it if it wasn't already created
    
            static CObject *SetParameters(param A, param B);
    
            CObject();
            CObject(param A, param B);
    
            bool CheckParameters(param A, param B);   // return true if object has the same parameters
            void methodA();
        private:
            static CObject * mTheObject;
    }
    
    CObject * CObject::getInstance()
    {
      if (!mTheObject)
              mTheObject=new CObject;   // assumes you have supplied a default constructor
      return mTheObject;
    }
    
    CObject CObject::SetParameters(param A, param B)
    {
          if (!mTheObject)
              mTheObject = new CObject(A, B);
          else if (!mTheObject->CheckParameters(A, B))
          {
                if (we_want_exception_safety_and_can_tolerate_two_objects_existing_temporarily)
                {
                      CObject *temp = new CObject(A, B);
                      delete mTheObject;
                      mTheObject = temp;
                }
                else
                {
                      delete mTheObject;
                      mTheObject = new CObject(A, B);
                }
          }
          return mTheObject;
    }
    Both approaches require the user of your class to set the parameters once (the first approach does this after creating the first instance). They also allows for those parameters to be reset by the user. The difference is that the second approach does this by destroying any existing object and creating a new one.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If you want to construct your object with parameters, those seem a bit complicated. Why not just use a create function and always do the creation in there instead of inside getInstance.

  8. #8
    In the Land of Diddly-Doo g4j31a5's Avatar
    Join Date
    Jul 2006
    Posts
    476
    Thanks to all of you. I get it now.
    ERROR: Brain not found. Please insert a new brain!

    “Do nothing which is of no use.” - Miyamoto Musashi.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to make a Packet sniffer/filter?
    By shown in forum C++ Programming
    Replies: 2
    Last Post: 02-22-2009, 09:51 PM
  2. "Cannot make pipe"
    By crepincdotcom in forum C Programming
    Replies: 5
    Last Post: 08-16-2004, 12:43 PM
  3. HELP!wanting to make full screen game windowed
    By rented in forum Game Programming
    Replies: 3
    Last Post: 06-11-2004, 04:19 AM
  4. make all rule
    By duffy in forum C Programming
    Replies: 9
    Last Post: 09-11-2003, 01:05 PM
  5. Replies: 6
    Last Post: 04-20-2002, 06:35 PM