Re: Single Object Instance Techniques
"SasQ" <sasq1@go2.pl> wrote in message
news:pan.2007.03.17.15.22.58.415509@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