singleton

E

E. Robert Tisdale

Could somebody please help me with the definition of a singleton?
cat singleton.cc
class {
private:
// representation
int A;
int B;
public:
//functions
const
int& a(void) const { return A; }
int& a(void) { return A; }
const
int& b(void) const { return B; }
int& b(void) { return B; }
} singleton;
 
D

Deming He

E. Robert Tisdale said:
Could somebody please help me with the definition of a singleton?

class {
private:
// representation
int A;
int B;
public:
file://functions
const
int& a(void) const { return A; }
int& a(void) { return A; }
const
int& b(void) const { return B; }
int& b(void) { return B; }
} singleton;

Here you go...

class singleton{
enum {MAX_INSTANCE=1};
static int num_of_instances;
// representation
int A;
int B;
public:
// functions
const int& a(void) const { return A; }
int& a(void) { return A; }
const int& b(void) const { return B; }
int& b(void) { return B; }

static singleton* get_a_singleton_instance();
};


singleton* singleton::get_a_singleton_instance()
{
if(num_of_instances<MAX_INSTANCE){
++num_of_instances;
return new singleton;
}
else
return null;
}

int singleton::num_of_instances = 0;
 
M

Mike Wahler

Deming He said:
Here you go...

class singleton{
enum {MAX_INSTANCE=1};
static int num_of_instances;

This would probably be better as an unsigned int,
since you don't need the possiblity of a negative
number of instances, do you? :)
// representation
int A;
int B;
public:
// functions
const int& a(void) const { return A; }
int& a(void) { return A; }
const int& b(void) const { return B; }
int& b(void) { return B; }

static singleton* get_a_singleton_instance();
};


singleton* singleton::get_a_singleton_instance()
{
if(num_of_instances<MAX_INSTANCE){
++num_of_instances;
return new singleton;
}
else
return null;

Better make that:

return NULL;

or

return 0;

C++ doesn't define any identifier 'null'.

int singleton::num_of_instances = 0;

-Mike
 
J

Jumbo

Deming He said:
Here you go...

class singleton{
enum {MAX_INSTANCE=1};
static int num_of_instances;
// representation
int A;
int B;
public:
// functions
const int& a(void) const { return A; }
int& a(void) { return A; }
const int& b(void) const { return B; }
int& b(void) { return B; }

static singleton* get_a_singleton_instance();
};


singleton* singleton::get_a_singleton_instance()
{
if(num_of_instances<MAX_INSTANCE){
++num_of_instances;
return new singleton;
}
else
return null;
}

int singleton::num_of_instances = 0;

You can still create more than one of them i.e:
int main(){
singleton sg1;
singleton sg2;
return 0;
}

I don't believe this is a singleton.
 
A

Avi Bercovich

Jumbo
You can still create more than one of them i.e:
int main(){
singleton sg1;
singleton sg2;
return 0;
}

I don't believe this is a singleton.

I'm pretty new to C++ so I may be totally wrong, but doesn't the fact
that num_of_instances is declared as static make sure that there is only
one actual instance of that variable accross all possible instances of
this singleton class?

If so then the code above should work as advertised. No?

grts,

avi
 
M

Michael Mellor

Deming said:
Here you go...

class singleton{
enum {MAX_INSTANCE=1};
static int num_of_instances;
// representation
int A;
int B;
The following should stop users creating extra singletons, etc.
singleton() { }
singleton(const singleton&);
singleton& operator=(const singleton&);
public:
// functions
const int& a(void) const { return A; }
int& a(void) { return A; }
const int& b(void) const { return B; }
int& b(void) { return B; }

static singleton* get_a_singleton_instance();
};


singleton* singleton::get_a_singleton_instance()
{
if(num_of_instances<MAX_INSTANCE){
++num_of_instances;
return new singleton;
}
else
return null;
}

int singleton::num_of_instances = 0;
It would be better to return a smart pointer cointing the instance
because the singleton class doesn't clean up after itself.

If you only need one singleton then the following is simpler:
singleton* singleton::get_a_singleton_instance()
{
static singleton the_instance;
return &the_instance;
}
but you have no control over when the object is destroyed during program
termination.

Michael Mellor
 
C

Chris Theis

[SNIP]
singleton* singleton::get_a_singleton_instance()
{
if(num_of_instances<MAX_INSTANCE){
++num_of_instances;
return new singleton;
}
else
return null;
}

The problem is that the use is responsible to destroy the created objects.
However, it's a good principle that whatever creates has to destroy!
Furthermore as long as you don't protect your ctor and copy ctor this is no
singleton 'cause there is easy access to instantiate an object!
int singleton::num_of_instances = 0;

Chris
 
C

Chris Theis

E. Robert Tisdale said:
Could somebody please help me with the definition of a singleton?

class {
private:
// representation
int A;
int B;
public:
//functions
const
int& a(void) const { return A; }
int& a(void) { return A; }
const
int& b(void) const { return B; }
int& b(void) { return B; }
} singleton;

The easiest principle is the so called "Meyers singleton". This simply
returns a reference to a static instance of an object. The following is a
generic implementation of a singleton wrapper which you can use with
whatever object you want. Of course there are some guidelines you should
stick to. The object that becomes a singleton must be derived from
CNonCopyable to prevent sneaky copy construction and so on. Furthermore the
wrapped class must include a friend declaration for the singleton wrapper to
allow access.

template<class T/*, class Tag = void*/>
class CSingleton
{
private:
CSingleton(void) {}
~CSingleton(void) {}

CSingleton( const CSingleton& rhs );
CSingleton& operator=( const CSingleton& rhs);

public:
static T& Instance() { // Meyers singleton
static T m_Instance;
return m_Instance;
}
};

class CNonCopyable {
protected:
CNonCopyable() {};
virtual ~CNonCopyable() {};
private:
CNonCopyable( const CNonCopyable& rhs );
CNonCopyable& operator=(const CNonCopyable& rhs );
};

The following as an example how to implement a wrapped singleton object

class CObj : public CNonCopyable {
protected:
CObj() {};
public:
~CObj() {};
friend class CSingleton<CObj>; // Attention: this must be
provided to enable the singleton wrapper to construct an object
int m_i;
};

Usage:

CObj& MyObj = CSingleton<CObj>::Instance();
// The following should not work as sneaky copies are prevented by
inheritance of CNonCopyable
CObj Sneaky( CSingleton<CObj>::Instance() );

HTH
Chris
 
J

Jumbo

Avi Bercovich said:
Jumbo

I'm pretty new to C++ so I may be totally wrong, but doesn't the fact
that num_of_instances is declared as static make sure that there is only
one actual instance of that variable accross all possible instances of
this singleton class?

If so then the code above should work as advertised. No?
Well no , you are right that a static variable is global across all
instances of the class but this does not prevent us from creating loads of
instances of that class.
It only keeps count of the new instances the class creates itself.
Therefore that class can only create ONE instance with is static method but
we can create loads of insatnaces of that class. SO the class isn't a
singleton.

A true singleton works using abractation , a bit like COM. Where you cannot
create an instance directly but you can create a pointer to an interface and
then you can call on the interface to create instances. A class factory it's
sometimes known as.

I might get round to trying to post an example but don't have time right
now.I've done this before and need to refresh my memory but it's quite
advanced OOP IIRC.
 
D

Deming He

Jumbo @uko2.co.uk> said:
You can still create more than one of them i.e:
int main(){
singleton sg1;
singleton sg2;
return 0;
}

I don't believe this is a singleton.
Yeah, you're correct. Why not add a "private" default cstor for "singleton"
class?
 
J

Jumbo

Deming He said:
Yeah, you're correct. Why not add a "private" default cstor for "singleton"
class?
Yes.
Something like this? :

#include <iostream>

class Singleton{
private:
friend class S;
Singleton(){std::cout<<"Singleton constructor"<<'\n';}
~Singleton(){std::cout<<"Singleton destructor"<<'\n';}
Singleton& operator=(const Singleton& rhs){}
Singleton(const Singleton& rhs){}
};

class S{
private:
static int count;
S(){}
public:
static int getCount(){return count;}
static Singleton* CreateSingleton(){
if(!count){
count++;
return new Singleton;
}else return 0;
}
static ReleaseSingleton(Singleton* p){
delete p;
count--;
}
};
int S::count = 0;

int main(){
Singleton* s1 = S::CreateSingleton();
S::ReleaseSingleton(s1);
s1=0;
std::cout<< "No of Singletons: " << S::getCount() << std::endl;
Singleton* s2 = S::CreateSingleton();
Singleton* s3 = S::CreateSingleton();
/*s3 is null*/
std::cout<< "No of Singletons: " << S::getCount() << std::endl;
S::ReleaseSingleton(s2);

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top