473,396 Members | 1,879 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

A constrained singleton sanity check

I am attempting to create a singleton, and was wondering if someone
could give me a sanity check on the design - does it accomplish my
constraints, and/or am I over complicating things. My design
constraints/environment are as follows:

1) Everything is single-threaded during static initialization (as in
prior to the open brace of main)
2) The environment may be multi-threaded during nominal program
execution (within {} of main)
3) I want a guaranteed destructor call to the singleton (excluding
exceptions, or other abnormal circumstances).
4) Other static (and/or) global objects may access the singleton
during their destructors.

The real kicker I was working to accommodate for above is #4. The
Idea I had was to basically hand out reference-counted containers for
the singleton. The tricky part was giving the guarantee that static/
global objects could reference the singleton in their destructors.
The idea was that even after {} main exits, the reference count is
reduced to zero and the singleton is destroyed, but some object's
destructor could still ressurect the singleton by asking for an
instance (which would presumably be destroyed again shortly after the
local use of that reference was destroyed). I tried to minimize the
code as much as possible, sorry in advance it being 117 lines...

//Header

#include <iostream>
using namespace std;

#ifndef SINGLETON_H_
#define SINGLETON_H_

void _Lock();
void _Unlock();

class Singleton;

class SingletonReference {
friend class Singleton;
public:

virtual ~SingletonReference();
SingletonReference(const SingletonReference &source);
Singleton& Get();

protected:

SingletonReference(Singleton **ppInstance);

private:

Singleton *m_pInstance;
};

class Singleton {
friend class SingletonReference;
public:

static SingletonReference Instance();
virtual ~Singleton() {}
void DoSomething();

protected:

Singleton() {}

private:

static Singleton* AddReference();
static void RemoveReference();
Singleton(const Singleton&) {}

static Singleton* s_pInstance;
static size_t s_count;
static SingletonReference s_instance; //Optional, keep-alive to
avoid lots of destroy/realloc

}; //class Singleton

#endif //SINGLETON_H_

//Implementation

//static
Singleton* Singleton::s_pInstance = NULL;
size_t Singleton::s_count = 0;
SingletonReference s_instance = Singleton::Instance();

void _Lock() {
//Some Implementation defined lock*/
}
void _Unlock() {
//Some Implementation defined unlock*/
}

SingletonReference::~SingletonReference() {
Singleton::RemoveReference();
}

SingletonReference::SingletonReference(const SingletonReference
&source)
: m_pInstance(NULL) {
Singleton::AddReference();
m_pInstance = source.m_pInstance;
}

Singleton& SingletonReference::Get() {
return *m_pInstance;
}

SingletonReference::SingletonReference(Singleton **ppInstance)
: m_pInstance(NULL) {
Singleton::AddReference();
m_pInstance = *ppInstance;
}

SingletonReference Singleton::Instance() {
return SingletonReference(&s_pInstance);
}

void Singleton::DoSomething() { cout << "Hi" << endl; }

Singleton* Singleton::AddReference() {
_Lock();
if (s_pInstance == NULL) {
s_pInstance = new Singleton();
s_count = 1;
}
else
s_count++;
_Unlock();
return s_pInstance;
}

void Singleton::RemoveReference() {
_Lock();
if (--s_count == 0)
{
delete s_pInstance;
s_pInstance = NULL;
}
_Unlock();
}
Jun 27 '08 #1
3 1766
stevewilliams2...@comcast.net wrote:
I am attempting to create a singleton, and was wondering if
someone could give me a sanity check on the design - does it
accomplish my constraints, and/or am I over complicating
things. My design constraints/environment are as follows:
1) Everything is single-threaded during static initialization (as in
prior to the open brace of main)
2) The environment may be multi-threaded during nominal program
execution (within {} of main)
3) I want a guaranteed destructor call to the singleton (excluding
exceptions, or other abnormal circumstances).
4) Other static (and/or) global objects may access the singleton
during their destructors.
Do you ever actually need both 3 and 4 in the same program?
The real kicker I was working to accommodate for above is #4.
4 is easy. So is 3. Both together become very difficult, if
not impossible.
The Idea I had was to basically hand out reference-counted
containers for the singleton. The tricky part was giving the
guarantee that static/ global objects could reference the
singleton in their destructors. The idea was that even after
{} main exits, the reference count is reduced to zero and the
singleton is destroyed, but some object's destructor could
still ressurect the singleton by asking for an instance (which
would presumably be destroyed again shortly after the local
use of that reference was destroyed).
But a resurected singleton isn't the same instance as the
original singleton. If you resurected, it's not really a
singleton anymore.

Note that your code may cause multiple creations during program
start-up as well. All it guarantees is that there is never more
than one instance of a singleton alive at any given time. Which
is fine if the singleton has no variable state, but if it has no
variable state, one can argue that there's no need for it to be
a singleton in the first place.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #2
On Apr 18, 2:10 am, James Kanze <james.ka...@gmail.comwrote:
Do you ever actually need both 3 and 4 in the same program?

But a resurected singleton isn't the same instance as the
original singleton. If you resurected, it's not really a
singleton anymore.

Note that your code may cause multiple creations during program
start-up as well. All it guarantees is that there is never more
than one instance of a singleton alive at any given time. Which
is fine if the singleton has no variable state, but if it has no
variable state, one can argue that there's no need for it to be
a singleton in the first place.
Well, the the singleton in this program is actually behaving as a
proxy for a remote object outside the program (and eventually might be
even across a network), which does have a variable state. The purpose
of this singleton is to open the remote connection, provide the remote
interface, and cleanly close the connection when it is done. So in
fact I don't mind a few extra open/close pairs during static/global
init or during static/global cleanup - because this is only for the
brief periods of program startup and shutdown (I don't like it, but
can live with it if I am still satisfying my constraints).
I care more that:
1) No messages to the remote server are lost (at least the code on
this end does everything it can to ensure this), such as another
static/global object that needs to utilize the remote log service
during its destructor to record important diagnostic info.
2) The connection is cleanly closed so there won't be issues trying to
reconnect if the client (this module) restarts suddenly. I can't
touch the server code, and it likes the client to disconnect before
allowing it to connect again.

Maybe I'm approaching the whole problem a bit wrong, it just seemed to
me the singleton was the closest to what I needed but it ended up
needed much more tweaking than I expected.

Thanks,
I do very much appreciate your feedback
Jun 27 '08 #3
On 18 avr, 18:24, stevewilliams2...@comcast.net wrote:
On Apr 18, 2:10 am, James Kanze <james.ka...@gmail.comwrote:
Do you ever actually need both 3 and 4 in the same program?
But a resurected singleton isn't the same instance as the
original singleton. If you resurected, it's not really a
singleton anymore.
Note that your code may cause multiple creations during program
start-up as well. All it guarantees is that there is never more
than one instance of a singleton alive at any given time. Which
is fine if the singleton has no variable state, but if it has no
variable state, one can argue that there's no need for it to be
a singleton in the first place.
Well, the the singleton in this program is actually behaving as a
proxy for a remote object outside the program (and eventually might be
even across a network), which does have a variable state. The purpose
of this singleton is to open the remote connection, provide the remote
interface, and cleanly close the connection when it is done. So in
fact I don't mind a few extra open/close pairs during static/global
init or during static/global cleanup - because this is only for the
brief periods of program startup and shutdown (I don't like it, but
can live with it if I am still satisfying my constraints).
OK. It's a special case. I wouldn't make it a generic
solution. (99% of the time, I don't need a destructor in my
singletons.) But if it solves a specific problem, why not?

[...]
Maybe I'm approaching the whole problem a bit wrong, it just
seemed to me the singleton was the closest to what I needed
but it ended up needed much more tweaking than I expected.
Well, it's not a singleton in the true sense, but it could be
what you need in this special case.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Tim Clacy | last post by:
Is there such a thing as a Singleton template that actually saves programming effort? Is it possible to actually use a template to make an arbitrary class a singleton without having to: a)...
16
by: cppaddict | last post by:
Hi, In this tutorial on singleton class in C++ (http://gethelp.devx.com/techtips/cpp_pro/10min/10min0200.asp) the author gives two implementations of a simple singleton class, claiming that...
3
by: Alicia Roberts | last post by:
Hello everyone, I have been researching the Singleton Pattern. Since the singleton pattern uses a private constructor which in turn reduces extendability, if you make the Singleton Polymorphic...
1
by: Capstar | last post by:
Hi NG, I was reading about Singletons on devX. http://gethelp.devx.com/techtips/cpp_pro/10min/10min0200.asp This is their class: class Singleton { public: static Singleton* Instance();
15
by: Mountain Bikn' Guy | last post by:
Is the second version shown below better? I couldn't locate enough info about in order to tell. 1.. My commonly used singleton pattern implementation looks like this (it was inspired by Eric...
13
by: William Stacey | last post by:
FYI. /// <summary> /// Author: William Stacey /// Fast and simple way to implement a singleton pattern without resorting /// to nested classes or other static vodo. Can also be easily converted...
7
by: Stephen Brown | last post by:
I have some strange behavior on my web server that seems to point to garbage collection. I have a singleton that tracks web activity on my web site. The singleton works great, except that it...
5
by: Rich | last post by:
The following code produced a singleton object with application scope when it should have had page scope: public class Singleton { private static Singleton uniqueInstance = null; private...
29
by: Ugo | last post by:
Hi guys, how do you make a singleton access class? Do you know a better way of this one: var singletonClass = (function( ) { // Private variable var instance = null;
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.