Re: How to define an global object like cout?
On Oct 19, 7:20 am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
Gianni Mariani wrote:
PengYu...@gmail.com wrote:
I want to define an unique file object, like cout, where there is the
only such one in the program.
It seems that singleton pattern can be used for this purpose. But I'm
wondering if cout is an singleton. I would guess not. There were some
threads in the newsgroup discuss about cout and singleton, which is
too long for me to catch the main point. Can somebody give me a brief
introduction on this? And show me how to define an global file object?
....
// public header file myiostream.h
#include <iostream>
namespace MYSPACE
{
extern std::ostream & MYOSTREAM;
} // end namespace
....
....
// implementation file - myiostream.cpp
#include "myiostream.h"
#include <fstream>
namespace { // anon namespace
struct my_fstream : std::fostream
{
std::fostream m_fostream;
my_fstream()
: m_fostream( "file name" );
{
// do whatever you want to open the file before main()
// is called here
}
};
my_fstream s_mostream;
}// end anon namespace
namespace MYSPACE
{
// create object - mostream
std::ostream & MYOSTREAM = s_mostream;
} // end namespace
....
///// not tested in a compiler - I probably broke somthing but you
///// should get the drift
I have this vague recollection that this will not completely
cut it as far as implementing a resource like std::cin is
concerned (the problem being something along the lines that
std::cin can be used in several compilation units and one
cannot decide up front which one shall do the initialization).
I think, there is a trick that goes by the name of Schwarz
counter used in solving the problem. Anyway, I don't remember
the details.
The problem is order of initialization, and there are several
ways to work around it. If you're writing new code, just
require the user to call a function to get a reference to the
object, and use the classical singleton idiom. (If the iostream
were being designed today, we'd probably write cin(), and not
just cin.)
The Schwarz counter idiom (also known as the nifty counter
idiom) depends on some way of defining the static object so that
the constructor won't be called by the normal start-up, then
calling it explicitly (using placement new) the first time the
object is wanted. (In the case of iostream, this is done in the
constructor of std::ios::Init.) There is, as far as I know, no
standard guaranteed way of allocating the object, however. One
simple solution is simply to declare the memory in assembler. I
think g++ uses some special extension. And in the past,
although technically not guaranteed at all, I've had fairly good
experience with a special, no-op constructor:
MyType staticObject( specialTypeForNoOpCtor ) ;
The Schwarz counter idiom works, of course, because the counter
itself is zero initialized before anything else runs. If you
can design your class so it works correctly with just zero
initialization, then the no-op constructor above can handle
everything; you don't even need the special counter.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34