[comp.lang.c++] Allowing only one instantiation of a class

rdas@hatter.Tops.Sun.COM (Robin Das) (10/12/89)

How do you allow only one instantation of a class across a system?

jima@hplsla.HP.COM (Jim Adcock) (10/13/89)

//heres one approach:

extern "C" 
{
  int printf(char* p, ...);
  void exit(int condition);
};

class oneonly
{
  const char* const nm;
  static int oneexists;
public:
  oneonly(const char* const name):nm(name)
  {
    if (oneexists) {printf("Sorry: oneonly already exists\n"); exit(1);}
    else           printf("this is the one and only oneonly: %s\n",nm);
    oneexists=1;
  }
};

int oneonly::oneexists=0;

// Lets see what happens when we try this: ---------------------------------

oneonly theFirstOne("theFirstOne");

void main()
{
  oneonly theSecondOne("theSecondOne");
  oneonly* p = new oneonly("new_oneonly");
}

nagle@well.UUCP (John Nagle) (10/14/89)

In article <672@suntops.Tops.Sun.COM> rdas@hatter.Tops.Sun.COM (Robin Das) writes:
>
>How do you allow only one instantation of a class across a system?

     Well, you could write

      class onceonly {
	static unsigned char instances = 0;
	...
	onceonly()
	{	assert(instances==0);
		instances++;
	}
      };

which ought to get the idea across.   There's no way to express the idea
in a way that the compiler will enforce it.

					John Nagle

strange@cbnewsl.ATT.COM (philip.e.brown) (10/14/89)

In article <672@suntops.Tops.Sun.COM> rdas@hatter.Tops.Sun.COM (Robin Das) writes:
>
>How do you allow only one instantation of a class across a system?

If you can name the instantiation, it's as simple as:

	class { /*...*/ } instance;

Since you haven't named the type, there is no handle for
additional instances.

---------
Phil Brown
strange@attunix.att.com

wmm@sdti.com (William M. Miller) (10/19/89)

In article <672@suntops.Tops.Sun.COM> rdas@hatter.Tops.Sun.COM (Robin Das) writes:
>
>How do you allow only one instantation of a class across a system?

There are lots of ways.  It really depends on what you want to do if some
code attempts to violate the constraint.

For example, if you want to detect unauthorized allocations at compile time,
make the constructor private and then have a single "friend" function whose
sole job is to allocate the single system-wide instance.  That way, any code
which tries to create an object of the restricted type will be flagged as
illegal by the compiler.  (If you think you need to, you can also put a
static counter into the friend to make sure it is called only once, too.)

If you want to generate a runtime error, you can put a static int member
into the class and have the constructor increment it and complain if the
count goes over 1 (static members of classes are shared among all instances
and are initialized to 0 unless you say differently).

If you want to allow multiple allocations and have them all refer to the
same object, you can combine the two previously-mentioned approaches after
a fashion: give the restricted class a private constructor and make an
access class a friend.  The friend will have a static pointer to the
restricted class; its constructor will check the pointer and only allocate
an instance if it is NULL.  All references to the restricted class instance
are made through the access class objects.
-- 
Non-disclaimer:  My boss and I always see eye-to-eye (every time I look in
the mirror).

...!genrad!mrst!sdti!wmm