PDA

View Full Version : Singleton pattern - end in recursion



probine
28th March 2006, 22:45
I have created a simple Singleton program. Is has 3 classes: main, Client, and LoginGui.

main.cpp


# include "logingui.h"
# include "client.h"
# include <iostream>
using namespace std;

int main()
{
cout << "Class main()\n";
Client* client = Client::clientInstance();
LoginGui* loginGui = LoginGui::loginGuiInstance();
return 1;
}


Client.cpp


# include "logingui.h"
# include "client.h"
# include <iostream>
using namespace std;

Client* Client :: _clientInstance = 0;

Client* Client :: clientInstance()
{
if(_clientInstance == 0)
{
_clientInstance = new Client;
}
return _clientInstance;
}


Client :: Client()
{
cout << "class Client() - Constructor\n";
numberInstances++;
cout << "class Client() - numberInstances: " << numberInstances << "\n";
loginGui = LoginGui::loginGuiInstance();
}



LoginGui.cpp

# include "client.h"
# include "logingui.h"
# include <iostream>
using namespace std;

LoginGui* LoginGui:: _loginGuiInstance = 0;

LoginGui* LoginGui:: loginGuiInstance()
{
if(_loginGuiInstance == 0)
{
_loginGuiInstance = new LoginGui;
}
return _loginGuiInstance;
}

LoginGui :: LoginGui()
{
cout << "class LoginGui() - Constructor\n";
numberInstances++;
cout << "class LoginGui() - numberInstances: " << numberInstances << "\n";

client1 = Client::clientInstance();
}


The pattern is suppose to create only one instance of a class, but when the Client class calls the LoginGui class, it ends in recursion.

Why ?

jacek
28th March 2006, 23:01
Why ?
Because _clientInstance is 0. You will have to find some other way (than calling xxxInstance() in constructor) to connect those two classes.

PS. Don't you think that three threads on the same subject is a bit too much?

Brandybuck
29th March 2006, 04:11
The classic singleton pattern has private contstructors, and provides a static instance() method. Use along with a mutex to prevent race conditions, and you're set.

probine
29th March 2006, 09:47
Sorry for the htree Threads in the same subject... I didn't know how to show the code with colors, therefore I post it again.

The problem is that in main I instantiate Client and LoginGui, so when I try to instantiate them again, it shouldn't be aproblem, because the only thing I get back is the only an only one instance of the classes.

probine
29th March 2006, 10:59
The mutex idea doesn't work either.

In class Client.cpp


QMutex mutex;
mutex.lock();
loginGui = LoginGui::loginGuiInstance();
mutex.unlock();



In LoginGui.cpp


QMutex mutex;
mutex.lock();
client = Client::clientInstance();
mutex.unlock();

jacek
29th March 2006, 14:05
Sorry for the htree Threads in the same subject... I didn't know how to show the code with colors, therefore I post it again.
Next time, please, use the "Edit" button.

Do you really need to obtain those instances in constructors?
Try something like this:
ClientGui::clientInstance()->setLoginGui( LoginGui::loginGuiInstance() );

wysota
29th March 2006, 14:08
Try this:


class A {
A();
B *b;
public:
static A *instance();
}

class B {
B(A*);
A *a;
public:
static B *instance(A *v=0);
}

A::A(){
b=0;
}

B::B(A *v){
a = v;
}

A* A::instance(){
static A *_inst=0;
if(!_inst){
_inst = new A();
_inst->b = B::instance(_inst);
}
return _inst;
}

B* B::instance(A *v){
static B *_inst=0;
if(_inst){
_inst = new B(v);
}
return _inst;
}