473,669 Members | 2,371 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Problem with variation on the Singleton pattern


I am implementing a variation on the Singleton design pattern, that
allows up to 8 objects of a class to be instantiated, and returns a
null pointer for anything more than 8.

I am running into a compile problem with GNU g++.

Here is the code:

/*************** ***** FILE sample.h *************** *****/

#ifndef SAMPLE_H
#define SAMPLE_H

class Allow_8_Objects
{
public:

// Destructor is public so that it can be executed by
// "delete"ing the pointer to the object. Note that the
// Contstructor is protected so it can't be executed
// from the outside with "new" (one of the rules for
// the Singleton design pattern).
//
~Allow_8_Object s();

static Allow_8_Objects * MakeInstance( void );
// This method creates an object of this class, and
// returns its pointer. Returns NULL if no more
// objects can be made or some other error
// happened.

protected:

Allow_8_Objects ();
// Protected constructor as part of the implementation
// of a modified Singleton design pattern (modified to
// allow 8 instances).

private:

static Allow_8_Objects * theInstance;
// an instance of this class. Static
// because it is used by MakeInstance(), which is
// static. This pointer is what is returned by
// MakeInstance().

static int numInstances;
// number of instances in existence. Cannot
// exceed maxObjects. Note: static.
};

#endif // SAMPLE_H

/*************** * END OF FILE sample.h *************** **/

/*************** *************** *************** **********/

/*************** **** FILE sample.cpp *************** ****/

#include "sample.h"

static const int maxObjects = 8;
// Maximum of 8 objects allowed per node

int Allow_8_Objects ::numInstances = 0;

Allow_8_Objects ::Allow_8_Objec ts()
{
}

Allow_8_Objects ::~Allow_8_Obje cts()
{
}

/********** HERE IS THE METHOD WITH THE PROBLEM **********/

// Make another object if not already at max.
//
Allow_8_Objects * Allow_8_Objects ::MakeInstance( void )
{
theInstance = (Allow_8_Object s*)NULL;

// If we already have the max number of objects, leave
// the return pointer set to NULL, else make a new object
// and get ready to return its pointer.
//
if ( numInstances < maxObjects )
{
theInstance = new Allow_8_Objects ;
}
return theInstance;
}

/*************** END OF FILE sample.cpp *************** */

Note that MakeInstance( ) is static, and theInstances and numInstances
are both static. So, MakeInstance shouldn't have any trouble
accessing theInstances and numInstances, right?

What happens when I compile this is that the cimpiler complains about
"undefined reference to Allow_8_Objects ::theInstance" at lines 1, 7,
and 11 of MakeInstance(). It can find and compile numInstances just
fine (line 9 of MakeInstance()) , just not theInstance.

Any ideas?
Feb 18 '06 #1
5 1736
On Sat, 18 Feb 2006 10:38:02 -0500, Eric
<re************ ****@nospam.no> wrote:

I am implementing a variation on the Singleton design pattern, that
allows up to 8 objects of a class to be instantiated, and returns a
null pointer for anything more than 8.

I am running into a compile problem with GNU g++.

Here is the code:

/*************** ***** FILE sample.h *************** *****/

#ifndef SAMPLE_H
#define SAMPLE_H

class Allow_8_Objects
{
public:

// Destructor is public so that it can be executed by
// "delete"ing the pointer to the object. Note that the
// Contstructor is protected so it can't be executed
// from the outside with "new" (one of the rules for
// the Singleton design pattern).
//
~Allow_8_Object s();

static Allow_8_Objects * MakeInstance( void );
// This method creates an object of this class, and
// returns its pointer. Returns NULL if no more
// objects can be made or some other error
// happened.

protected:

Allow_8_Objects ();
// Protected constructor as part of the implementation
// of a modified Singleton design pattern (modified to
// allow 8 instances).

private:

static Allow_8_Objects * theInstance;
// an instance of this class. Static
// because it is used by MakeInstance(), which is
// static. This pointer is what is returned by
// MakeInstance().

static int numInstances;
// number of instances in existence. Cannot
// exceed maxObjects. Note: static.
};

#endif // SAMPLE_H

/*************** * END OF FILE sample.h *************** **/

/*************** *************** *************** **********/

/*************** **** FILE sample.cpp *************** ****/

#include "sample.h"

static const int maxObjects = 8;
// Maximum of 8 objects allowed per node

int Allow_8_Objects ::numInstances = 0;

Allow_8_Object s::Allow_8_Obje cts()
{
}

Allow_8_Object s::~Allow_8_Obj ects()
{
}

/********** HERE IS THE METHOD WITH THE PROBLEM **********/

// Make another object if not already at max.
//
Allow_8_Object s* Allow_8_Objects ::MakeInstance( void )
{
theInstance = (Allow_8_Object s*)NULL;

// If we already have the max number of objects, leave
// the return pointer set to NULL, else make a new object
// and get ready to return its pointer.
//
if ( numInstances < maxObjects )
{
theInstance = new Allow_8_Objects ;
}
return theInstance;
}

/*************** END OF FILE sample.cpp *************** */

Note that MakeInstance( ) is static, and theInstances and numInstances
are both static. So, MakeInstance shouldn't have any trouble
accessing theInstances and numInstances, right?

What happens when I compile this is that the cimpiler complains about
"undefined reference to Allow_8_Objects ::theInstance" at lines 1, 7,
and 11 of MakeInstance(). It can find and compile numInstances just
fine (line 9 of MakeInstance()) , just not theInstance.

Any ideas?


You are getting a linker error because you didn't initialize
theInstance. It compiles just fine, at least on my compiler, but it
won't link. Put this in your .cpp file:

Allow_8_Objects *Allow_8_Object s::theInstance = 0;

Also, you don't #include whatever header defines NULL (probably
stddef.h??). But using 0 works just as well.

Some other things to think about:

(1) You have declared the default constructor protected, implying that
other classes will eventually derive from this one. If you ever delete
such a class through the base class pointer, you need to provide a
virtual destructor. Otherwise, you get undefined behavior.

(2) When someone deletes an instance of the class, what happens
(should happen) to numInstances?

(3) What about copying and assignment? Generally you wouldn't want to
allow copying a singleton, but since you have more than one, perhaps
it would make sense. If not, you should declare these private but
don't implement them.

(4) You'll need to think about synchronization issues in case these
objects will be created in different threads.

(5) Since you have a fixed ceiling of eight objects, I wonder if it
wouldn't make more sense to create eight static objects up front and
that way avoid the ensuing memory management problems? But we don't
have enough information yet about what you are trying to do.

--
Bob Hairgrove
No**********@Ho me.com
Feb 18 '06 #2
On Sat, 18 Feb 2006 17:41:28 +0100, Bob Hairgrove
<in*****@bigfoo t.com> wrote:
You are getting a linker error because you didn't initialize
theInstance. It compiles just fine, at least on my compiler, but it
won't link. Put this in your .cpp file:

Allow_8_Object s *Allow_8_Object s::theInstance = 0;
Good afternoon, Bob.

Thanks, that did it. :-)

And thanks for your other items of advice. I will consider each and
will probably implement most. I'm relatively new at C++, about 2
years' experience over the last 4 years (though I have about 21 years'
experience with C) and some of the more exotic features of the
language like virtual destructors still leave me scratching my head a
bit. But, I'm learning. :-)
(2) When someone deletes an instance of the class, what happens
(should happen) to numInstances?
It should (will) get set to zero, as will the pointer to the instance
of the class.
(3) What about copying and assignment? Generally you wouldn't want to
allow copying a singleton, but since you have more than one, perhaps
it would make sense. If not, you should declare these private but
don't implement them.
I don't think that I plan to copy them (if I understand correctly what
you mean), but what do you mean by declaring these private (what are
"these") but not implementing them?
(4) You'll need to think about synchronization issues in case these
objects will be created in different threads.
Fortunately this is a single-threaded application so I'm pretty safe
there.
(5) Since you have a fixed ceiling of eight objects, I wonder if it
wouldn't make more sense to create eight static objects up front and
that way avoid the ensuing memory management problems? But we don't
have enough information yet about what you are trying to do.


The reason I don't do that is that not all 8 of them will necessarily
get used, in fact most often only one will be used, occasionally two,
rarely more than that, and if they don't get used I don't want them
occupyingr memory unnecessarily.

Thanks...

Eric
Feb 18 '06 #3
On Sat, 18 Feb 2006 15:26:41 -0500, Eric
<re************ ****@nospam.no> wrote:
On Sat, 18 Feb 2006 17:41:28 +0100, Bob Hairgrove
<in*****@bigfo ot.com> wrote:
You are getting a linker error because you didn't initialize
theInstance . It compiles just fine, at least on my compiler, but it
won't link. Put this in your .cpp file:

Allow_8_Objec ts *Allow_8_Object s::theInstance = 0;
Good afternoon, Bob.

Thanks, that did it. :-)


:)
And thanks for your other items of advice. I will consider each and
will probably implement most. I'm relatively new at C++, about 2
years' experience over the last 4 years (though I have about 21 years'
experience with C) and some of the more exotic features of the
language like virtual destructors still leave me scratching my head a
bit. But, I'm learning. :-)
(2) When someone deletes an instance of the class, what happens
(should happen) to numInstances?


It should (will) get set to zero, as will the pointer to the instance
of the class.
(3) What about copying and assignment? Generally you wouldn't want to
allow copying a singleton, but since you have more than one, perhaps
it would make sense. If not, you should declare these private but
don't implement them.


I don't think that I plan to copy them (if I understand correctly what
you mean), but what do you mean by declaring these private (what are
"these") but not implementing them?


If you don't declare them, the compiler will generate default versions
of the copy constructor and the assignment operator for you.
Unfortunately, there might not do what you want. E.g., if you allocate
memory dynamically anywhere and have a pointer as member variable, you
will want to make sure that the memory is actually copied and not just
the pointer. Therefore, to ensure that objects are properly copied,
you need to implement a copy constructor and assignment operator that
do the right thing.

However, if you wish to disallow copying and assignment, you can
declare the copy constructor and the assignment operator as "private"
and simply leave out any implementation or function body for these.
That way, the compiler will generate an error when a client tries to
copy or assign to one of the objects.
(4) You'll need to think about synchronization issues in case these
objects will be created in different threads.


Fortunately this is a single-threaded application so I'm pretty safe
there.
(5) Since you have a fixed ceiling of eight objects, I wonder if it
wouldn't make more sense to create eight static objects up front and
that way avoid the ensuing memory management problems? But we don't
have enough information yet about what you are trying to do.


The reason I don't do that is that not all 8 of them will necessarily
get used, in fact most often only one will be used, occasionally two,
rarely more than that, and if they don't get used I don't want them
occupyingr memory unnecessarily.


How did you come up with the magic number 8 in that case? Seems to me
to be a bit arbitrary...

--
Bob Hairgrove
No**********@Ho me.com
Feb 18 '06 #4
On Sat, 18 Feb 2006 22:21:22 +0100, Bob Hairgrove
<in*****@bigfoo t.com> wrote:
How did you come up with the magic number 8 in that case? Seems to me
to be a bit arbitrary...


Mostly because the project engineer said "Allow for a maximum of 8"
and I snapped to attention, rendered a brisk salute, and said "Yes,
sir". :-)
Feb 19 '06 #5
Eric wrote:
On Sat, 18 Feb 2006 22:21:22 +0100, Bob Hairgrove
<in*****@bigfoo t.com> wrote:
How did you come up with the magic number 8 in that case? Seems to me
to be a bit arbitrary...


Mostly because the project engineer said "Allow for a maximum of 8"
and I snapped to attention, rendered a brisk salute, and said "Yes,
sir". :-)


Sure, but it's more fun like:

template <size_t n>
class allow_n_instanc es;

:)

Luke

Feb 19 '06 #6

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

Similar topics

3
3470
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
2416
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
2030
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
2479
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...
15
63902
by: DBA | last post by:
Hi All, What is the diff. between a singleton class and a static class in C#?
13
3054
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.
5
5370
by: tobias.sturn | last post by:
Hi! I have written this template for making a singleton: #define DECLARE_SINGLETON(classname) \ private: \ static classname* m_pThis; \ classname(); \ class Guard \ { \ public: \
7
1419
by: ThunderMusic | last post by:
Hi, I have a problem regarding singletons in C#. What I would like to do is the following ClassA is a singleton ClassB inherits from ClassA and is also a Singleton there cannot and instance of ClassA and an instance of ClassB, there must be only one of one or the other... Is there a way to do it? or it's simply not possible?
3
18240
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
8462
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8382
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,...
1
8586
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8658
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...
0
7405
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6209
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
5682
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4384
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2028
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.