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

Single Object Instance Techniques

Why would anyone write:

class SomeThing // class littered with non-domain single-instancing code :(
{
private:
SomeThing();
static SomeThing* pInstance_;
public:

static SomeThing* getInstance()
{
if(!pInstance_)
{
pInstance_ = new SomeThing();
}
return pInstance_;
}
};
SomeThing* SomeThing::pInstance_ = 0;

instead of this:

class SomeThing // class unencumbered by single-instancing concerns :)
{
public:
SomeThing();
};

SomeThing* GetSomeThing() // single-instancing accessor function
{
static SomeThing* thing = new SomeThing();
return thing;
}

???

Is it because the second example only solves the problem but doesn't ensure
that someone won't call the constructor elsewhere? That's it isn't it.
Single-instance techniques help with the initialization order problem, and
the second form works great for that. I don't think single instance control
belongs in a domain class. 'SingleInstancer' should be a template class.
What's your opinion?

John
Mar 17 '07 #1
13 5352
There is no advantage. If I saw that code I would guess someone came
from an object oriented only language, and didn't know of direct
namespaces. It's clearly an attempt to allow only one instance of the
class, but it doesn't actually enforce it. Alternative, a struct with
only static member functions could have been used.

Another disadvantage is that it makes it impossible for the class to
be allocated on the stack faster.

Mar 17 '07 #2
JohnQ wrote:
Why would anyone write:

class SomeThing // class littered with non-domain single-instancing code
:(
{
private:
SomeThing();
static SomeThing* pInstance_;
I don't have the book Design Patterns to hand. Under Singleton, does it show
the above code, or this correct code below?
SomeThing* GetSomeThing() // single-instancing accessor function
{
static SomeThing* thing = new SomeThing();
return thing;
}
If you must Singleton, do it like that.

However, Singleton is a very abusable pattern when it enables rampant
coupling. The "instantiate once" motivation is not the same as the
"available to everyone like a big fat global" motivation. The latter is an
antipattern!
... 'SingleInstancer' should be a template class.
Such a template is often the result of a junior effort with Singleton. I
don't think it solves the problem how to prevent secondary instantiation of
the templated type.

Furtherless, if you have unit tests, you _need_ secondary instatiation, so
you can fake objects for your tests!

Singletons should be treated with high suspicion.

--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
Mar 17 '07 #3
Single-instance classes are contradictory to entire idea of OOP.
You're essentially making an object, and using object syntax, just for
its namespace. I recommend instead using an actualy namespace and a
procedural paradigm.

Mar 17 '07 #4
Single-instance classes are contradictory to entire idea of OOP.
You're essentially making an object, and using object syntax, just for
its namespace. I recommend instead using an actual namespace and a
procedural paradigm.

Mar 17 '07 #5
Single-instance classes are contradictory to entire idea of OOP.
You're essentially making an object, and using object syntax, just for
its namespace. I recommend instead using an actual namespace and a
procedural paradigm.

Mar 17 '07 #6
Single-instance classes are contradictory to the entire idea of OOP.
You're essentially making an object, and using object syntax, just for
its namespace. I recommend instead using an actual namespace and a
procedural paradigm.

Mar 17 '07 #7
em************@gmail.com wrote:
Single-instance classes are contradictory to the entire idea of OOP.
You're essentially making an object, and using object syntax, just for
its namespace. I recommend instead using an actual namespace and a
procedural paradigm.
Why have you posted the same message (without any context) four times?

--
Ian Collins.
Mar 17 '07 #8
On Mar 16, 8:17 pm, Ian Collins <ian-n...@hotmail.comwrote:
emery.denuc...@gmail.com wrote:
Single-instance classes are contradictory to the entire idea of OOP.
You're essentially making an object, and using object syntax, just for
its namespace. I recommend instead using an actual namespace and a
procedural paradigm.

Why have you posted the same message (without any context) four times?

--
Ian Collins.
Sorry. Google groups was bugging out on me. It was giving me failure
messages, then it decided to work on my fourth or fifth attempt. It
appears to be working fine now, even though only the final message
shows up in Google groups, but the total-messages count is in excess
of 4. *shrugs*

Mar 17 '07 #9
Phlip wrote:
JohnQ wrote:
>Why would anyone write:

class SomeThing // class littered with non-domain single-instancing code
:(
{
private:
SomeThing();
static SomeThing* pInstance_;

I don't have the book Design Patterns to hand. Under Singleton, does it show
the above code, or this correct code below?
>SomeThing* GetSomeThing() // single-instancing accessor function
{
static SomeThing* thing = new SomeThing();
return thing;
}

If you must Singleton, do it like that.
Aren't those two equivalent Philip? The only difference that I see is
that the pointer is directly class accessible and accessible to the
outside only via the function (which does the test on first use
explicitly, instead of implicitly by way of the static inside of the
function). Although, I guess that the compiler may be able to do some
optimisations using the implicit test? What do you think?
However, Singleton is a very abusable pattern when it enables rampant
coupling. The "instantiate once" motivation is not the same as the
"available to everyone like a big fat global" motivation. The latter is an
antipattern!
>... 'SingleInstancer' should be a template class.

Such a template is often the result of a junior effort with Singleton. I
don't think it solves the problem how to prevent secondary instantiation of
the templated type.
Do you say this because of how some linkers may work? I think that most
(if not all) of the newer linkers are supposed to amalgamate all
statically linked multiple instances of the same templates. DLLs and
shared memory spaces are a different matter. It would require extra
care and would have to incorporate that into your design of your
application system.
Furtherless, if you have unit tests, you _need_ secondary instatiation, so
you can fake objects for your tests!
I don't agree. You can do unit tests on a singleton. In fact, your
domain is somewhat narrowed with a singleton as since there is only one
instance floating around, you don't have to worry about interactions
with others of the same type, and can optimise based on that pattern.
Singletons should be treated with high suspicion.
Singletons are just like most patterns. Design patterns are a way of
sharing insight on common problems and are useful. This limits but does
not eliminate the abuse of such patterns.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 17 '07 #10
Dnia Sat, 17 Mar 2007 02:48:54 +0000, JohnQ napisa³(a):
Why would anyone write:

class SomeThing
{
private:
SomeThing();
static SomeThing* pInstance_;
public:
static SomeThing* getInstance()
{
if (!pInstance_)
{
pInstance_ = new SomeThing();
}
return pInstance_;
}
};
SomeThing* SomeThing::pInstance_ = 0;
Maybe because he's a stuntman ;)
Think about where is a delete operator called for the
object pointed by pInstance_ ? When is a destructor called?
Answer is: never :P and it's not good :/
The other flaw is returning a pointer to internal data,
because it gives an opportunity for someone to call 'delete'
on this pointer and deallocate that internal, private object.
There is also nothing to stop you from copy-construct the
additional objects of that class, because copy constructor
wasn't declared private.

Instead, I advice you the Meyers's approach:

class SomeThing
{
public:
// Returning by reference ensures that calling delete
// on the returned object will cause a compiler error.
static SomeThing& getInstance()
{
// The following object will be allocated in a static
// memory, but initialized only once, upon first call
// of this function, with the use of private constructor.
// Further calls will only return that single instance.
// Object will be properly destructed [using destructor]
// when the program ends.
static SomeThing instance;
return instance;
}
// ...other public interface...

private:
// Declaring the following as private prevents illegal
// creations of more instances.
SomeThing();
SomeThing(const SomeThing&);
SomeThing& operator=(const SomeThing&);
};

Example of use:

SomeThing obj = SomeThing::getInstance();
obj.someMethod();
delete obj; //error: not a pointer :)
SomeThing::getInstance().someMethod();
class SomeThing // class unencumbered by single-instancing concerns :)
If you don't want only one single instance, but you only want to
have global access to that object and prevent static initialization
order fiasco, you don't need that pattern.
SomeThing* GetSomeThing() // single-instancing accessor function
Accessor? But it's not a member of any class.
I would rather call it factory/creation function ;)
{
static SomeThing* thing = new SomeThing();
return thing;
}
Yes, that function returns always the same one instance of
SomeThing, but doesn't prevent from creating more instances
in the other place in a program.
Single-instance techniques help with the initialization
order problem
But not ONLY with that ;)
and the second form works great for that.
It's not. Still someone may try to create some global
instances depending on other global objects in a program
[and their initialization before theirs].
I don't think single instance control belongs in a
domain class.
And what do you think about a cloning/copying domain? :)
'SingleInstancer' should be a template class.
Or an interface. But it's not that simple.

--
SasQ
Mar 17 '07 #11
Dnia Sat, 17 Mar 2007 16:23:02 +0100, SasQ napisa³(a):
Example of use:

SomeThing obj = SomeThing::getInstance();
Sorry for a little mistake, I meant:

SomeThing& obj = SomeThing::getInstance();

of course ;)

--
SasQ
Mar 17 '07 #12

"SasQ" <sa***@go2.plwrote in message
news:pa****************************@go2.pl...
Dnia Sat, 17 Mar 2007 02:48:54 +0000, JohnQ napisa³(a):
>Why would anyone write:

class SomeThing
{
private:
SomeThing();
static SomeThing* pInstance_;
public:
static SomeThing* getInstance()
{
if (!pInstance_)
{
pInstance_ = new SomeThing();
}
return pInstance_;
}
};
SomeThing* SomeThing::pInstance_ = 0;

Maybe because he's a stuntman ;)
Think about where is a delete operator called for the
object pointed by pInstance_ ? When is a destructor called?
Answer is: never :P and it's not good :/
The other flaw is returning a pointer to internal data,
because it gives an opportunity for someone to call 'delete'
on this pointer and deallocate that internal, private object.
There is also nothing to stop you from copy-construct the
additional objects of that class, because copy constructor
wasn't declared private.

Instead, I advice you the Meyers's approach:

class SomeThing
{
public:
// Returning by reference ensures that calling delete
// on the returned object will cause a compiler error.
static SomeThing& getInstance()
{
// The following object will be allocated in a static
// memory, but initialized only once, upon first call
// of this function, with the use of private constructor.
// Further calls will only return that single instance.
// Object will be properly destructed [using destructor]
// when the program ends.
static SomeThing instance;
return instance;
}
// ...other public interface...

private:
// Declaring the following as private prevents illegal
// creations of more instances.
SomeThing();
SomeThing(const SomeThing&);
SomeThing& operator=(const SomeThing&);
};

Example of use:

SomeThing obj = SomeThing::getInstance();
obj.someMethod();
delete obj; //error: not a pointer :)
SomeThing::getInstance().someMethod();
>class SomeThing // class unencumbered by single-instancing concerns :)

If you don't want only one single instance, but you only want to
have global access to that object and prevent static initialization
order fiasco, you don't need that pattern.
>SomeThing* GetSomeThing() // single-instancing accessor function

Accessor? But it's not a member of any class.
I would rather call it factory/creation function ;)
It's a factory the first time it is called. After that, it is an accessor.
>
>{
static SomeThing* thing = new SomeThing();
return thing;
}

Yes, that function returns always the same one instance of
SomeThing, but doesn't prevent from creating more instances
in the other place in a program.
>Single-instance techniques help with the initialization
order problem

But not ONLY with that ;)
>and the second form works great for that.

It's not. Still someone may try to create some global
instances depending on other global objects in a program
[and their initialization before theirs].
>I don't think single instance control belongs in a
domain class.

And what do you think about a cloning/copying domain? :)
I don't know what you're talking about with that.
>
>'SingleInstancer' should be a template class.

Or an interface. But it's not that simple.
I guess the work on this topic seems to be on how to create one of those
things for other people to use. If you're building something just for your
own use, you don't need all the controls. Things like that are hard to build
outside of the language implementation probably. Just like it's hard if not
impossible to get a class to act like a pointer.

I had a follow-up question to post after this one about the threading
concerns (aka, DCL issues), but it escapes me at this time. I'll post it if
I remember where I was going with this.

John
Mar 26 '07 #13

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

Similar topics

54
by: Jerry | last post by:
What are the advantages and disadvantages of using Object Oriented PHP vs Java?
11
by: DrUg13 | last post by:
In java, this seems so easy. You need a new object Object test = new Object() gives me exactly what I want. could someone please help me understand the different ways to do the same thing in...
6
by: Martin | last post by:
I'd like to be able to get the name of an object instance from within a call to a method of that same object. Is this at all possible? The example below works by passing in the name of the object...
16
by: Elad | last post by:
Hi, I have an application that is made up of several executables. I need all these executables to use the same instance of an object. What is the best, most efficient way to approach this? ...
8
by: Lance | last post by:
I've been teaching myself C# for a few months now and I have a concept problem. I know how to instantiate an object from a class I’ve created, but now I want to retrieve and store data in a...
11
by: Kevin Prichard | last post by:
Hi all, I've recently been following the object-oriented techiques discussed here and have been testing them for use in a web application. There is problem that I'd like to discuss with you...
73
by: Water Cooler v2 | last post by:
I am new to PHP, just one day new. But I am otherwise a seasoned programmer on many other languages like C, VB 6, C#, VB.NET, Win32 platform and have some tiny bit experience in MFC, C++, Python. ...
2
by: Ralph | last post by:
Hi I don't understand why it's not working: function schedule(imTop){ this.tdImagesTop = imTop; } schedule.prototype.selectEl = function() { alert(this.tdImagesTop);
4
by: yadin | last post by:
class big(self): x = 32 list = def inside (self): class small(self): # a new class defined inside the first y = 348 list.append(y) # send the value to first list
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: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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
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
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.