2010年6月18日星期五

Thinking about Singleton

1. The constructor should not have parameters?
In the GoF Design Patterns, there is no parameter for the constructor. That makes it very easy, because the constructor is invoked by the instance() method, if the constructor needs parameters, do we send the parameters to the instance() method, which pass them to the constructor? It is not clean and clear.

class Singleton {
public:
static Singleton *instance();
protected:
Singleton();
private:
static Singleton *s_pInstance;
};

But if the the constructor do need some parameters, how to do that?

2. The constructor need to be protected/privated?
In the GoF Design Patterns, the constructor is protected, which make sure that the clients (from outside) can not instantiate objects directly.
But if we want to create a new Singleton instance?

class Singleton {
public:
static Singleton* createNewInstance();
static Singleton* instance();
protected:
Singleton();
private:
static Singleton *s_pInstance;
};

The following is an example. For example, a new scene is created whenever a scene file is loaded/read.
Scene* Scene::s_pThis= 0;
Scene* Scene::instance() {
if (s_pThis) {
return s_pThis;
} else {
return createNewScene();
}
}
Scene* createNewScene() {
if (s_pInstance ) {
// delete, this will call the deconstructor.
delete s_pThis;
s_pThis= 0;
}
s_pThis= new Scene;
return s_pThis;
}

In this case, the instance() returns the object instance which is active, others are discarded.
And in this case, we can change it a little bit:
(1) firstly, call this method to create instance.
static Singleton* createNewInstance(...parameters...);
(2) call the instance() use the instance object.
This makes a assumption that, create it before you use it.

3. The copy constructor and assignment operator ?
See this example:
Scene s = *Scene::instance(); // this will call the copy constructor.
Scene s; // this will call the default constructor.
void functionX(Scene s) {
s is a temp instance object...
}
functionX(*Scene::instance()); // this will call the copy constructor;
Maybe, it would be safer to private these two methods.

4. How about the s_pInstance in derived class?

没有评论:

发表评论