473,770 Members | 4,718 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C++ Singleton Pattern

Why aren't "Singletons " done like this in C++:

A.hpp:

class A
{
public: static A theA;

// ...

private:
A() { /* ... */ }
};

A.cpp:

A A::theA;

rather than the complicated approaches I've
seen with the instance being allocated with "new"?

Dec 13 '06 #1
10 3331
wk****@yahoo.co m wrote:
Why aren't "Singletons " done like this in C++:

A.hpp:

class A
{
public: static A theA;

// ...

private:
A() { /* ... */ }
};

A.cpp:

A A::theA;

rather than the complicated approaches I've
seen with the instance being allocated with "new"?
Actually some of them are. Why do you say they aren't?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 13 '06 #2

wk****@yahoo.co m wrote:
Why aren't "Singletons " done like this in C++:

A.hpp:

class A
{
public: static A theA;

// ...

private:
A() { /* ... */ }
};

A.cpp:

A A::theA;
Whats stopying me from copying an instance of A?

int main()
{
A b(A::theA);
}
>
rather than the complicated approaches I've
seen with the instance being allocated with "new"?
How about:

#include <iostream>
#include <ostream>

template< typename T >
T& instance() // by reference only
{
static T t;
return t;
}

class A {
friend A& instance< A >();
A() { std::cout << "A()\n"; }
A(const A& copy) { std::cout << "copy A\n"; }
public:
~A() { std::cout << "~A()\n"; }
};

int main()
{
A& r_a = instance< A >();
// A a = instance< A >(); // error
std::cout << "&r_a = " << &r_a << std::endl;
A& r_b = instance< A >();
std::cout << "&r_b = " << &r_b << std::endl;
}

/*
A()
&r_a = 0x501fe0
&r_b = 0x501fe0
~A()
*/

Dec 13 '06 #3
wk****@yahoo.co m a écrit :
Why aren't "Singletons " done like this in C++:

A.hpp:

class A
{
public: static A theA;
private:
A() { /* ... */ }
};

A.cpp:

A A::theA;

rather than the complicated approaches I've
seen with the instance being allocated with "new"?
Your approach is dangerous, as you don't know when the object is
created. You are only able to successfully use it after you entered in
main(), and you should not use it after main() exit. It means that your
singleton cannot be used in static object construction and so on - note
that this might not be a problem in the end.

Meyer's singleton (the getInstance() function declares a static
variable and returns this variable) was probably what you got in mind -
the standard ensures that the static is constructed the first time you
entered in the function, so it is always valid - until you quit main()
(static objects order of destruction is well defined, but not easily
handled from the programmer point of view, so you'd better not use it
after you exit main()). Allocating the instance using new() in the
getInstance() function allows the same use as Meyer's singleton, but
the singleton is still valid until the memory is freed. If it is never
freed then you singleton is always valid.

* Your approach
class A
{
private:
static A theA;
A() { }
~A() { }
A(const A&) { }
A& operator=(const A&);
public:
// time of construction is not known by the programmer
// time of destruction is not known by the programmer
A& instance() { return theA; }
};

* Meyer's approach
class A
{
private:
A() { }
~A() { }
A(const A&) { }
A& operator=(const A&);
public:
// the instance will be created when you enter the
// function for the first time
// time of destruction is hard to tell from the programmer
// point of view
A& instance() { static A a; return a; }
};

* GoF approach:
class A
{
private:
A() { }
~A() { }
A(const A&) { }
A& operator=(const A&);
public:
// the instance will be created when you enter the
// function for the first time
// the instance is never destroyed
A& instance() { static A *a = NULL; if (!a) a = new A(); return a; }
};

There's a very interesting discussion about singleton and their
possible implementation in the Modern C++ book of Andrei Alexandrescu.

Regards,

-- Emmanuel Deloget, Artware

Dec 13 '06 #4
Salt_Peter wrote:
wk****@yahoo.co m wrote:
Why aren't "Singletons " done like this in C++:

A.hpp:

class A
{
public: static A theA;

// ...

private:
A() { /* ... */ }
};

A.cpp:

A A::theA;

Whats stopying me from copying an instance of A?

int main()
{
A b(A::theA);
}
Yes, good point, I forgot the private undefined copy constructor.

rather than the complicated approaches I've
seen with the instance being allocated with "new"?

How about:

#include <iostream>
#include <ostream>

template< typename T >
T& instance() // by reference only
{
static T t;
return t;
}

class A {
friend A& instance< A >();
A() { std::cout << "A()\n"; }
A(const A& copy) { std::cout << "copy A\n"; }
public:
~A() { std::cout << "~A()\n"; }
};
So the reason for this is to avoid having, for classes with
all inline member functions (the exceptional case i would
think), a .cpp file that defines the single private instance?

Dec 13 '06 #5
Emmanuel Deloget wrote:
wk****@yahoo.co m a écrit :
Why aren't "Singletons " done like this in C++:

A.hpp:

class A
{
public: static A theA;
private:
A() { /* ... */ }
};

A.cpp:

A A::theA;

rather than the complicated approaches I've
seen with the instance being allocated with "new"?

Your approach is dangerous, as you don't know when the object is
created. You are only able to successfully use it after you entered in
main(), and you should not use it after main() exit. It means that your
singleton cannot be used in static object construction and so on - note
that this might not be a problem in the end.

Meyer's singleton (the getInstance() function declares a static
variable and returns this variable) was probably what you got in mind -
the standard ensures that the static is constructed the first time you
entered in the function, so it is always valid - until you quit main()
(static objects order of destruction is well defined, but not easily
handled from the programmer point of view, so you'd better not use it
after you exit main()). Allocating the instance using new() in the
getInstance() function allows the same use as Meyer's singleton, but
the singleton is still valid until the memory is freed. If it is never
freed then you singleton is always valid.

* Your approach
class A
{
private:
static A theA;
A() { }
~A() { }
A(const A&) { }
A& operator=(const A&);
public:
// time of construction is not known by the programmer
// time of destruction is not known by the programmer
A& instance() { return theA; }
};

* Meyer's approach
class A
{
private:
A() { }
~A() { }
A(const A&) { }
A& operator=(const A&);
public:
// the instance will be created when you enter the
// function for the first time
// time of destruction is hard to tell from the programmer
// point of view
A& instance() { static A a; return a; }
};
My understanding is that the standard allows local statics to
be initialized any time before the line of executable code
following their definition is executed. So I don't see how
this addresses the order-of-intialization problem.
* GoF approach:
class A
{
private:
A() { }
~A() { }
A(const A&) { }
A& operator=(const A&);
public:
// the instance will be created when you enter the
// function for the first time
// the instance is never destroyed
A& instance() { static A *a = NULL; if (!a) a = new A(); return a; }
};
I dislike this because of the added overhead to every single access
to the instance.

(Insert by reference here any of the long heated threads about
whether minor optimizations are worth it.)

The are also cases where the fact that the instance is not
destroyed can be a problem. If the instance sets some
sort of lock flag in a file or in a shared memory segment,
the file will close/segment will detach on program exit,
but the lock flag won't be cleared.

Dec 13 '06 #6
wk****@yahoo.co m wrote:
[..]
My understanding is that the standard allows local statics to
be initialized any time before the line of executable code
following their definition is executed. So I don't see how
this addresses the order-of-intialization problem.
Your understanding is incorrect. The local statics are initialised
when the control passes their initialisation for the first time.
[..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 13 '06 #7
Emmanuel Deloget wrote:
.....
// the instance will be created when you enter the
// function for the first time
// the instance is never destroyed
A& instance() { static A *a = NULL; if (!a) a = new A(); return a; }
// is this not the same ?
A& instance() { static A *a = new A(); return *a; }

With gcc, this is also thread-safe.
Dec 14 '06 #8
Victor Bazarov wrote:
wk****@yahoo.co m wrote:
[..]
My understanding is that the standard allows local statics to
be initialized any time before the line of executable code
following their definition is executed. So I don't see how
this addresses the order-of-intialization problem.

Your understanding is incorrect. The local statics are initialised
when the control passes their initialisation for the first time.
....

Since you likely know the case-law on this much better than
me, I will take your word on this. Looking at Draft 98, 6.7-4
seems to unnecessary go around the block a few times.
Why not just say local statics are intialized when control
passes them, undefined value before initialization, and let
the as-if rule allow for optimized early initialization?

The implication of this is that the compiler has to generate
a hidden static flag to prevent re-initialization, and that flag
has to be checked every time control passes the local static
definition.

Dec 14 '06 #9
wk****@yahoo.co m wrote:
....
The implication of this is that the compiler has to generate
a hidden static flag to prevent re-initialization, and that flag
has to be checked every time control passes the local static
definition.
Wait until you read about the order of destruction.
Dec 14 '06 #10

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

Similar topics

3
3477
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 what sort of problems/issues should be considered? Also, I see that a singleton needs to be set up with certain data such as file name, database URL etc. What issues are involved in this, and how would you do this? If someone knows about the...
4
2421
by: Neil Zanella | last post by:
Hello, I would be very interested in knowing how the following C++ multi-instance singleton (AKA Borg) design pattern based code snippet can be neatly coded in Python. While there may be somewhat unusual places where multi-instance singleton is more useful than plain singleton, it seems to me that the former leads to less coding, so unless I can somehow package the singleton pattern in a superclass (so I don't have to code it...
1
2038
by: Richard A. DeVenezia | last post by:
foo() generates elements with event handlers that invoke foo function properties. Is this an abhorrent or misthought pattern ? It allows just the one occurence of identifier /foo/ to be changed to /whatever/ when need arises and everything should still work. function foo () { var callee = arguments.callee
3
2498
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 what sort of problems/issues should be considered? Also, I see that a singleton needs to be set up with certain data such as file name, database URL etc. What issues are involved in this, and how would you do this? If someone knows about the...
11
2171
by: Daniel Billingsley | last post by:
Let's say I'm writing a business app and I want there to be only one instance of the Customer object for each particular customer (representing a database record) being edited. Would it be possible to extend the Singleton pattern to handle this? Assuming that my Customer class follows the Singleton pattern (particularly Skeet's 4th version) I'm thinking if I add private static SomeCollectionType customers;
21
2468
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 maybe a Template can be use for that, but C# does not support Templates (will be C# generics in mid 2005). Does anyone have a solution on how the singleton pattern can be written, in C#, as a framework/ infrastructure class, so users can use this...
13
3061
by: Robert W. | last post by:
At the beginning of my C# days (about 6 months ago) I learned about the Singleton pattern and implemented for Reference data, such as the kind that appears in an Options dialog box. My Singleton code looks like this: public sealed class Reference { private static readonly Reference instance = new Reference(); // Make the default constructor private, so that nothing can directly create it.
2
6347
by: Kevin Newman | last post by:
I have been playing around with a couple of ways to add inheritance to a JavaScript singleton pattern. As far as I'm aware, using an anonymous constructor to create a singleton does not allow any kind of inheritance: singletonObj = new function() { this.prop = true; } Here are two ways to create a singleton with inheritance:
3
2965
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 Singleton.__single
3
18253
weaknessforcats
by: weaknessforcats | last post by:
Design Pattern: The Singleton Overview Use the Singleton Design Pattern when you want to have only one instance of a class. This single instance must have a single global point of access. That is, regardless of where the object is hidden, everyone needs access to it. The global point of access is the object's Instance() method. Individual users need to be prevented from creating their own instances of the Singleton.
0
9432
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10059
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9873
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7420
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5313
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5454
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3974
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3578
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2822
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.