 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Dhruv Guest
|
Posted: Thu Jun 26, 2003 1:06 pm Post subject: Re: Limit Object Instances |
|
|
On Thu, 26 Jun 2003 05:41:22 -0700, amitpethkar wrote:
| Quote: | Hi All,
I want to know is it possible to limit the instances of C++ class.
for example
Suppose there is 1 instance created of a class and if you create
other instances they will refer to 1st instance itself instead of
constructing more objects
|
Create a static object. Or create a static object within the class of the
same type as the class.
-Dhruv.
|
|
| Back to top |
|
 |
Dimitris Kamenopoulos Guest
|
Posted: Thu Jun 26, 2003 1:14 pm Post subject: Re: Limit Object Instances |
|
|
amitpethkar wrote:
| Quote: | Hi All,
I want to know is it possible to limit the instances of C++ class.
|
Yes, it is.
| Quote: | for example
Suppose there is 1 instance created of a class and if you create
other instances they will refer to 1st instance itself instead of
constructing more objects
|
This special (and most useful) case is called "Singleton Design Pattern".
For single-threaded applications the implementation is reasonably
straightforward. Google for it, or better, check out Design Patterns by
Gamma et al. (ISBN 0201633612) to learn more about this and other design
patterns.
|
|
| Back to top |
|
 |
Evan Guest
|
Posted: Thu Jun 26, 2003 6:20 pm Post subject: Re: Limit Object Instances |
|
|
"Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote
| Quote: | Create a static object. Or create a static object within the class of the
same type as the class.
-Dhruv.
|
Both of these have drawbacks. First, by "create a static object" I
assume you mean one whose members are all static. However, static
functins are not virtual, so inheritance is crippled. Second, if you
object has initialization tasks, since there is no constructor, your
code has to be responsible for calling in Itin() method or similar.
Better to leave as few responsibilities to the client code as
possible. Same deal with the destructor. Adding a static object also
has issues; I'll discuss those after giving a quick overview of the
"correct" solution, the singleton (as Dimitris Kamenopoulos
mentioned).
You have your class:
class myClass (
public:
void DoStuff();
// blah blah blah... your other functions
Instead of using the new operator and the constructor in client code
(i.e. myClass* myObject;) you'll call an Instance function (myClass
myObject = myClass::Instance() . This has to be static.
(Unfortunately in some views at least, you'll find when dealing with
"Design Patterns" such as the singleton you'll be using lots of
pointers.)
myClass& Instance() {
if (_instance == NULL)
_instance = new myClass;
return _instance;
}
This is often done with pointers (i.e. Instance() will return a
myClass*), but this way will keep the client code from deleting it and
breaking everything. (This is actually prevented, even in this code,
my making the destructor private, but returning a reference keeps the
temptation away.) So much for the public interface.
private:
myClass* _instance;
This holds the pointer to the one object that is created. Now you have
a class the supports the singleton pattern. However, it doesn't
enforce it; client code can still createobjects of tye myClass. To
keep that from happening, we need to make thi constructors private,
even if you don't supply any (or C++ will provide you with them...
it'l like lawyers. "If you do not provide a constructor one will be
provided for you." Sorry.) Remember that this is in the private area
of the class.
myClass() {}
myClass(const myClass& arg) {}
(Both a zero-argument and copy constructor.) Also provided by the
compiler: the assignment operator.
myClass& operator=(const myClass&)
{return *_instance;}
The last thing to do is prevent people from deleting the objects (yes,
it's still possible even with the version of Instance() we use):
~myClass() {}
};
There's your singleton.
It's now possible to say why using a static object, rather than a
pointer is a bad idea. First, here are the changes to the class file:
// stuff...
myClass& Instance() {
return _instance;
}
private:
static myClass _instance;
// more stuff...
Now suppose you have the following code in another file:
int aGlobalVariable =
myClass::Instance().SomeFunctionThatReturnsAnInt();
The result is undefined because the construction order of the
_instance variable in myClass and aGlobalVariable is undefined. If
aGlobalVariable is constructed first, it will have a dead reference.
Second, if your object has large start up/tear down tasks then they
will be carried out regardless if the object is ever used.
Many thanks to both the Gang of Four's "Design Patterns" and Andrei
Alexandrescu's "Modern C++ Design" (which provided the problems with
both static implementations, as well as the reasoning for returning a
reference rather than a pointer).
|
|
| Back to top |
|
 |
amitpethkar Guest
|
Posted: Fri Jun 27, 2003 12:17 pm Post subject: Re: Limit Object Instances |
|
|
Dimitris Kamenopoulos <dkamen4spam (AT) cslab (DOT) ece.ntua.gr> wrote
| Quote: | amitpethkar wrote:
Hi All,
I want to know is it possible to limit the instances of C++ class.
Yes, it is.
for example
Suppose there is 1 instance created of a class and if you create
other instances they will refer to 1st instance itself instead of
constructing more objects
This special (and most useful) case is called "Singleton Design Pattern".
For single-threaded applications the implementation is reasonably
straightforward. Google for it, or better, check out Design Patterns by
Gamma et al. (ISBN 0201633612) to learn more about this and other design
patterns.
|
Thank you very much. I learnt concept called Singleton design pattern .
|
|
| Back to top |
|
 |
Dhruv Guest
|
Posted: Fri Jun 27, 2003 1:29 pm Post subject: Re: Limit Object Instances |
|
|
On Thu, 26 Jun 2003 11:20:14 -0700, Evan wrote:
| Quote: | "Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote
|
Hey, thanks I myself was unaware of this approach. It's somewhat like
virtual constructors, but without the virtual. I've been thinking of
getting hold of that book for a while, and this seems to be the right
time.
Regards,
-Dhruv.
|
|
| Back to top |
|
 |
Evan Guest
|
Posted: Sat Jun 28, 2003 4:20 am Post subject: Re: Limit Object Instances |
|
|
"Norbert Riedlin" <nr (AT) netatec (DOT) de> wrote
| Quote: | "Evan" <eed132 (AT) psu (DOT) edu> schrieb im Newsbeitrag
news:3f25c666.0306261020.5e1a55e7 (AT) posting (DOT) google.com...
...
myClass& Instance() {
if (_instance == NULL)
_instance = new myClass;
return _instance;
}
Obviously you meant
return *_instance
|
Oopsie... yes I did. Originally I had Instance returning a pointer
rather than a reference, but changed it after I had typed it. (This is
also why some of the wording of the surrounding text may seem a little
weird...)
Anyway, the rest of this is in reference to the remainder of your
comments (reproduced below as I have little to add and what I say
could get lost). I have nothing specific to add except to add a big
thank you for the info. It's only very recently that I've been
learning this material myself--I bought Design Patterns only within
the last two and a half weeks, and read the chapter in Alexandrescu's
book last weekend--so this stuff is new to me as well. I particularily
like the static local variable in Instance.
I just have one question. You say that often the implementation of the
assignment operator and I guess copy constructor are usually
omitted... wouldn't this produce a linker error? Or just if they are
called in client code? Or what's the deal?
| Quote: | This is often done with pointers (i.e. Instance() will return a
myClass*), but this way will keep the client code from deleting it and
breaking everything. (This is actually prevented, even in this code,
my making the destructor private, but returning a reference keeps the
temptation away.) So much for the public interface.
private:
myClass* _instance;
This holds the pointer to the one object that is created. Now you have
a class the supports the singleton pattern. However, it doesn't
enforce it; client code can still createobjects of tye myClass. To
keep that from happening, we need to make thi constructors private,
even if you don't supply any (or C++ will provide you with them...
it'l like lawyers. "If you do not provide a constructor one will be
provided for you." Sorry.) Remember that this is in the private area
of the class.
myClass() {}
myClass(const myClass& arg) {}
(Both a zero-argument and copy constructor.) Also provided by the
compiler: the assignment operator.
myClass& operator=(const myClass&)
{return *_instance;}
Often the implementation of these methods is omitted. Only a declaration is
provided.
The last thing to do is prevent people from deleting the objects (yes,
it's still possible even with the version of Instance() we use):
~myClass() {}
};
There's your singleton.
It's now possible to say why using a static object, rather than a
pointer is a bad idea. First, here are the changes to the class file:
// stuff...
myClass& Instance() {
return _instance;
}
private:
static myClass _instance;
// more stuff...
Now suppose you have the following code in another file:
int aGlobalVariable =
myClass::Instance().SomeFunctionThatReturnsAnInt();
The result is undefined because the construction order of the
_instance variable in myClass and aGlobalVariable is undefined. If
aGlobalVariable is constructed first, it will have a dead reference.
Second, if your object has large start up/tear down tasks then they
will be carried out regardless if the object is ever used.
What you say is all correct, but I would like to present another alternative
(and some of its gotchas)
The interface of the Instance method will be the same as in your example
but:
class myClass {
//...
myClass& Instance() {
static myClass instance;
return instance;
}
//...
};
First of all: never begin an identifier with an underscore. There are too
many things to remember, which identifiers are reserved for the
implementation and which may be used by your application. So better don't do
that.
Second: no 'if' involved, no dynamic memory usage. The disadvantage of
constructing instance_ at startup also disappears, it will be constructed,
as soon as Instance() is called for the first time.
Third: (not shown): the member variable 'instance_' (in your example
'_instance') vanishes from the class declaration.
Fourth (and not so obvious): 'instance's destructor will be called when the
application is going down. This may or may not be a good thing. You cann do
some cleanup, logging, writing persistence data, but imagine other
singletons, that depend on 'instance' when they shut down. On the othjer
hand, when you need the destructor being called, you have no other choice.
Fifth: The calling of the destructor has another implication: A private
destructor is ok according to the standard, but some compilers just don't
get it right (MSVC 6.0). Logically the destructor is called in the context
of Instance(), which has acces rights, but the code is generated somewher in
main()'s epilogue. Sigh, to be portable you have to stick with a public
destructor...
With the implications above and when you don't need 'instance's destructor
beeing called, I would stick to the following implication:
class myClass {
//...
myClass& Instance() {
static myClass* instance = new myClass();
return *instance;
}
//...
};
Essentially the implementation is then the same as yours, bearing the lack
of the member variable. (and the missing 'if')
Many thanks to both the Gang of Four's "Design Patterns" and Andrei
Alexandrescu's "Modern C++ Design" (which provided the problems with
both static implementations, as well as the reasoning for returning a
reference rather than a pointer).
Yeah, I would like to thank them too!
Norbert
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*** Usenet.com - The #1 Usenet Newsgroup Service on The Planet! ***
http://www.usenet.com
Unlimited Download - 19 Seperate Servers - 90,000 groups - Uncensored
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
|
| Back to top |
|
 |
Ramon Guest
|
Posted: Sat Jun 28, 2003 10:10 pm Post subject: Re: Limit Object Instances |
|
|
Is there any standard (or de facto standard) way to write a singleton
class?
Is there any template we need to use for this classes?
|
|
| Back to top |
|
 |
Ramon Guest
|
Posted: Sat Jun 28, 2003 10:16 pm Post subject: Re: Limit Object Instances |
|
|
<forgot one quetion>
Is there a naming convention for singleton classes?
|
|
| Back to top |
|
 |
Dhruv Guest
|
Posted: Wed Jul 02, 2003 8:06 am Post subject: Re: Limit Object Instances |
|
|
On Thu, 26 Jun 2003 11:20:14 -0700, Evan wrote:
| Quote: | "Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote
|
Hey, thanks I myself was unaware of this approach. It's somewhat like
virtual constructors, but without the virtual. I've been thinking of
getting hold of that book for a while, and this seems to be the right
time.
Regards,
-Dhruv.
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|