473,385 Members | 1,757 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,385 software developers and data experts.

C++ Singleton problem...

Hi!

I have written this template for making a singleton:
#define DECLARE_SINGLETON(classname) \
private: \
static classname* m_pThis; \
classname(); \
class Guard \
{ \
public: \
~Guard() \
{ \
if(classname::m_pThis != 0 ) \
delete classname::m_pThis; \
} \
}; \
friend class Guard; \
public: \
static classname* getInstance();

#define DEFINE_SINGLETON(classname) \
classname* classname::m_pThis=0; \
classname* classname::getInstance() \
{ \
static Guard guard; \
if(m_pThis == 0) \
{ \
m_pThis = new classname(); \
} \
return m_pThis; \
}

Now i have a class which uses these macros but now i still i can write
constructors make them public and i have won nothing...

class Class
{
public:
Class(int a) {/*i have created an object :(*/
Class(char a)...
};;

How could i make it not possible for the user of the template that he
cant override the constructor?

Thanks very much!!

Jun 15 '06 #1
5 5356
tobias.sturn wrote:
Now i have a class which uses these macros but now i still i can write
constructors make them public and i have won nothing...

class Class
{
public:
Class(int a) {/*i have created an object :(*/
Class(char a)...
};;
You can't. The point of classes is to be upgraded and re-used. Deal.
How could i make it not possible for the user of the template that he
cant override the constructor?


The mininimal situation worked for me:

class frob {
DECLARE_SINGLETON(frob);
};

DEFINE_SINGLETON(frob);
frob::frob() {}
#include <assert.h>
#include <stdlib.h>

int main()
{
frob * pFrob = frob::getInstance();
assert(NULL != pFrob);
// frob aFrob; // <-- bad
return 0;
}

Now about your style. "Singleton" is the most abused pattern in /Design
Patterns/, and it's the best candidate for time travel to tell the GOF to
take it out. I can think of many situations where a program needs only one
of something, but I can't think of any situation where a program should
never have more than one of something.

Next, you should use unit tests (like my main()), and should pass them after
every edit. This implies that some of your classes should use a mock object
instead of your singleton. So that implies that tests have legitimate
reasons to re-use more than one instance of your singleton, to construct
them with extra data, and to derive from them.

Next, a Singleton is not an excuse for a global variable. Most clients of
your singleton should pass it in by reference. They should not rely on it
floating around in space. So nearly all clients of your singleton should
accept a reference that your tests can mock.

Next, you are abusing macros. You should instead abuse templates. Google for
[c++ singleton template], and get sample code like this:

http://www.codeproject.com/cpp/singleton_template.asp

Next, neither your getInstance() nor the one on that page can return a NULL
pointer, so they should return a reference to the Singleton. Whichever
pattern you go with, make that small fix.

Next, I suspect this is the best implementation for the getter:

static T& Instance()
{
static T aT;
return aT;
};

That is well-defined to construct aT at least before the first time the
function enters, so it fixes the common C++ problem with global variables
constructing out of order, and fixes it without the odious choice of a 'new'
call. Other patterns and situations may easily apply here, too.

After applying any subset of my suggestions, you will have a better program
with less need to restrict your constructors.

--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
Jun 16 '06 #2

to**********@vol.at wrote:
Hi!

I have written this template for making a singleton:
#define DECLARE_SINGLETON(classname) \
private: \
static classname* m_pThis; \
classname(); \
class Guard \
{ \
public: \
~Guard() \
{ \
if(classname::m_pThis != 0 ) \
delete classname::m_pThis; \
} \
}; \
friend class Guard; \
public: \
static classname* getInstance();

#define DEFINE_SINGLETON(classname) \
classname* classname::m_pThis=0; \
classname* classname::getInstance() \
{ \
static Guard guard; \
if(m_pThis == 0) \
{ \
m_pThis = new classname(); \
} \
return m_pThis; \
}

Now i have a class which uses these macros but now i still i can write
constructors make them public and i have won nothing...

class Class
{
public:
Class(int a) {/*i have created an object :(*/
Class(char a)...
};;

How could i make it not possible for the user of the template that he
cant override the constructor?

Thanks very much!!


With the following Singleton class, you can create a Singleton use one
of two methods.
You can derive from Singleton as the foo example class does below, or
you can create a class like the Widget example class.

template<typename T>
class Singleton
{
protected:
Singleton(){}
~Singleton(){}
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
public:
class FriendClass
{
public:
FriendClass():m_MyClass(new T()){}
~FriendClass(){delete m_MyClass;}
T* m_MyClass;
};
static T& Instance() {
static FriendClass Instance;
return *Instance.m_MyClass;
}
};

class Widget {
private:
Widget(){}
~Widget(){}
Widget& operator=(const Widget&);
Widget(const Widget&);
public:
friend class Singleton<Widget>::FriendClass;
int m_i;
};
class foo : public Singleton<foo>{
private:
foo(){}
~foo(){}
foo& operator=(const foo&);
foo(const foo&);
public:
friend class FriendClass;
int m_i;
};
int main(int argc, char* argv[])
{
Widget& MyWidget = Singleton<Widget>::Instance();
foo& Myfoo = foo::Instance();

system("pause");
return 0;
}

Jun 16 '06 #3
Axter wrote:

You answered the wrong question. (I do that often enough I'm going to
crack down on you for it.)
class Widget {
private:
Widget(){}
~Widget(){}


One can still write 'public: Widget(something)' here, and construct the
Widget without the Singleton wrapper.

--
Phlip
Jun 16 '06 #4

Phlip wrote:
Axter wrote:

You answered the wrong question. (I do that often enough I'm going to
crack down on you for it.)
class Widget {
private:
Widget(){}
~Widget(){}


One can still write 'public: Widget(something)' here, and construct the
Widget without the Singleton wrapper.


Then you would not be creating a Singleton.
Widget is the target Singleton. When you create a Singleton, you want
your constructors to be private.

Jun 18 '06 #5
Axter wrote:
Then you would not be creating a Singleton. Widget is the target
Singleton. When you create a Singleton, you want your constructors to be
private.


That's the design answer (which I already provided). The technical answer
is you can't prevent Widget from having other constructors.

--
Phlip
Jun 18 '06 #6

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

Similar topics

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...
1
by: Jim Strathmeyer | last post by:
So I'm trying to implement a singleton template class, but I'm getting a confusing 'undefined reference' when it tries to link. Here's the code and g++'s output. Any help? // singleton.h ...
3
by: Harry | last post by:
Hi ppl I have a doubt on singleton class. I am writing a program below class singleton { private: singleton(){}; public: //way 1
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...
21
by: Sharon | last post by:
I wish to build a framework for our developers that will include a singleton pattern. But it can not be a base class because it has a private constructor and therefore can be inherit. I thought...
3
by: dischdennis | last post by:
Hello List, I would like to make a singleton class in python 2.4.3, I found this pattern in the web: class Singleton: __single = None def __init__( self ): if Singleton.__single: raise...
6
by: toton | last post by:
Hi, If I have a singleton class based on dynamic initialization (with new ) , is it considered a memory leak? Anything in C++ standard says about it ? And little off - topic question , If the...
3
by: wizwx | last post by:
There are two typical implementations of a singleton. The first one is to use a static pointer class Singleton { static Singleton * pSingleton; public: Singleton * instance() {...
2
by: Bob Johnson | last post by:
Just wondering the extent to which some of you are implementing classes as Singletons. I'm working on a brand new project and, early on, identified some obvious candidates. By "obvoius candidates"...
4
by: John Doe | last post by:
Hi, I have a singleton class defined like this : class UIManager : public CSingleton<UIManager>, public CObject { protected: DECLARE_DYNAMIC(UIManager) friend class CSingleton<UIManager>;
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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...

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.