Alexei's singletons

T

Tito

I have two questions about the singletons' chapter of Alexei Alexandrescu's
"C++ Modern Design".

1. In the beginning of the chapter Alexei states that a "singleton" class
implementation made of static member functions has the problem that the
functions are not virtual, so that you have to touch the class' code in
order to change the behaviour. But, how is a singleton meant to be inherited
from? Is not the concrete class of the unique instance already hardcoded in
the singleton's implementation?

2. We he presents his SetLongevity utility, he uses realloc instead of
new/delete, arguing that if not doing so, the data structure that
SetLongevity maintains would suffer of the same longevity problems as other
singletons. I do not understand that, because they are cleanly deleted on
atexit(). Can someone explain it to me?

Thanks,
Tito
 
A

Alf P. Steinbach

* "Tito said:
I have two questions about the singletons' chapter of Alexei Alexandrescu's
"C++ Modern Design".

That must be Andrei's little known brother.

1. In the beginning of the chapter Alexei states that a "singleton" class
implementation made of static member functions has the problem that the
functions are not virtual, so that you have to touch the class' code in
order to change the behaviour. But, how is a singleton meant to be inherited
from?

As with any other class.

Is not the concrete class of the unique instance already hardcoded in
the singleton's implementation?

It would be if you used the static member function pattern, and that's
the point.


2. We he presents his SetLongevity utility, he uses realloc instead of
new/delete, arguing that if not doing so, the data structure that
SetLongevity maintains would suffer of the same longevity problems as other
singletons. I do not understand that, because they are cleanly deleted on
atexit(). Can someone explain it to me?

I'm not sure what you're referring to here.
 
T

Truls Haaland

Tito said:
2. We he presents his SetLongevity utility, he uses realloc instead of
new/delete, arguing that if not doing so, the data structure that
SetLongevity maintains would suffer of the same longevity problems as other
singletons. I do not understand that, because they are cleanly deleted on
atexit(). Can someone explain it to me?

The objects contained in the pTrackerArray are deleted in AtExitFn(),
but the array itself is not. Since we do not know how many objects are
contained in pTrackerArray when AtExitFn() is called, we don't know
when to delete the array. But realloc(), as explained in the footnote
on page 143, can behave as both malloc and free. If you call it with
size>0 it behaves as malloc, and if you call it with size=0 it behaves
as free. This means that we can just call realloc() with the number of
objects in the array, and when the number of objects in the array
reaches zero the array is automagically deleted.

T.
 
A

Andy Venikov

2. We he presents his SetLongevity utility, he uses realloc instead of
new/delete, arguing that if not doing so, the data structure that
SetLongevity maintains would suffer of the same longevity problems as other
singletons. I do not understand that, because they are cleanly deleted on
atexit(). Can someone explain it to me?

Quick correction: Andrei, not Alexei.

Read carefully paragraph starting with "There is only one instance of
the Tracker type..."

It says, as I understand it, that TrackerArray is itself a singleton.
Yet it must be used by a function that manages singletons. That means
that you cannot apply singleton mechanism we're devising to the
TrackerArray.
The way Andrei went about solving this problem was to
use a contiguous c-style array, not a container, and manage the
allocation/deallocation of the whole array with low-level routines
that are guaranteed to work at any time.
AtExitFn does use delete() on LifetimeTracker object, as SetLongevity
creates them with new. But we're talking about an array of pointers to
LifetimeTracker objects whose size is controlled by reallocate.

HTH,
Andy.
 
S

Siemel Naran

1. In the beginning of the chapter Alexei states that a "singleton" class
implementation made of static member functions has the problem that the
functions are not virtual, so that you have to touch the class' code in
order to change the behaviour. But, how is a singleton meant to be inherited
from? Is not the concrete class of the unique instance already hardcoded in
the singleton's implementation?

If you inherit from a singleton, it means that you're creating many
instances of the singleton, each with a different behavior, and it's no
longer a singleton. Just my char(2) :).

2. We he presents his SetLongevity utility, he uses realloc instead of
new/delete, arguing that if not doing so, the data structure that
SetLongevity maintains would suffer of the same longevity problems as other
singletons. I do not understand that, because they are cleanly deleted on
atexit(). Can someone explain it to me?

Don't know what you're talking about. My guess is that new T calls
::eek:perator new to get memory (which may call std::malloc) and then a
constructor, so it has something to do with the constructor call. Similar
delete t calls the destructor the ::eek:perator delete.
 
T

Tito

1. In the beginning of the chapter Alexei states that a "singleton"
class
As with any other class.

Yes, but then you are having a subclass of your singleton without any
protection
against multiple instantiation:

Singleton* s1 = new DerivedSingleton;
Singleton* s2 = new DerivedSingleton; // !!!
It would be if you used the static member function pattern, and that's
the point.

No, it's already hardcoded in the usual way:

static Singleton& getInstance() {
if (!pInstance)
pInstance = new Singleton; // class hardcoded!!
return *pInstance;
}

Tito
 
T

Tito

1. In the beginning of the chapter Alexei states that a "singleton"
class
If you inherit from a singleton, it means that you're creating many
instances of the singleton, each with a different behavior, and it's no
longer a singleton. Just my char(2) :).

Exactly, that is one of the things, but, in addition,
- the class that is instantiated is hardcoded into the static Instance()
member function, so that you will get always the same behaviour by calling
Singleton::Instance(), no matter how you derive the class.
- Andrei makes the constructors of the Singleton private, so you *cannot*
derive from Singleton.

Tito
 
T

Tito

2. We he presents his SetLongevity utility, he uses realloc instead of
Quick correction: Andrei, not Alexei.

Read carefully paragraph starting with "There is only one instance of
the Tracker type..."

Yes, now I have read it too many times ;)
It says, as I understand it, that TrackerArray is itself a singleton.
Yet it must be used by a function that manages singletons. That means
that you cannot apply singleton mechanism we're devising to the
TrackerArray.

Yes, that is what I understand when reading the paragraph. But that is my
point: the TrackerArray is not a singleton, so I do not think that it is
"exposed to all the Singleton problems". It is a global variable in the
unnamed space, so it should no be accessed by any other code but the one
contained inside of SetLongevity, which is the only responsible of
maintaining the data structure.

More precisely, I do not understand:
- why is pTrackerArray "exposed to all the Singleton problems just
discussed",
- what is the problem in: "SetLongevity must be available at any time, yet
it has to manage private storage.",
- how malloc & co. come to help.

Tito
 
T

Tito

1. In the beginning of the chapter Alexei states that a "singleton"
Whether you have protection against that depends on the class.

No, if you let your singleton be inherited from, then anybody can create
multiple instances of it.
I read that as "yes, it's hardcoded that way"?

How do you build a singleton that instantiates a class that is not hardcoded
in its implementation?

Tito
 
A

Alf P. Steinbach

* "Tito said:
Yes, but then you are having a subclass of your singleton without any
protection
against multiple instantiation:

Singleton* s1 = new DerivedSingleton;
Singleton* s2 = new DerivedSingleton; // !!!

Whether you have protection against that depends on the class.

No, it's already hardcoded in the usual way:

static Singleton& getInstance() {
if (!pInstance)
pInstance = new Singleton; // class hardcoded!!
return *pInstance;
}

I read that as "yes, it's hardcoded that way"?
 
A

Alf P. Steinbach

* "Tito said:
No, if you let your singleton be inherited from, then anybody can create
multiple instances of it.

That turns out not to be correct.

A simple exercise for you: disprove your own statement.


How do you build a singleton that instantiates a class that is not hardcoded
in its implementation?

Read up on and (not the least) try out templates in C++.

Essentially that's what Andrei's SingletonHolder (if I remember the name
correctly) is all about.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top