[comp.std.c++] static member function for instance creation

delft@fwi.uva.nl (Andre van Delft) (10/28/90)

The Turbo C++ programmer's manual says:

  The main use of static members is to keep track of data common to all
  objects of a class, such as the number of objects created (...)

Thus a static member may be used for object creation (and I have a special
reason why I do not want a constructor). However its class cannot be
abstract, which I regret. I wanted 

class c {
  public:
    virtual void vf(int) = 0;
    static int n;
    static c* createOne() {n++; return new c;}  // NOT OK: c is abstract
}

class d:c {
  public:
    void vf(int) {}
}

void main() {
  d*anObject;
  anObject = d::createOne();
  ...
}

Am I overlooking something? Or should C++ permit the keyword "this" after 
the keyword "new", so that the following would be legal:

c* c::createOne() {n++; return new this;} // 'this' denotes the class!

Ok, I know I should use a constructor in such cases. I have a good reason to
want static members in abstract classes that make new instances:

I am currently working on a parallel extension to C++; this language,
Scriptic-C++, has simulation capabilities that are a bit comparable to
Simula. Scriptic offers a new, function-like refinement construct named
"script". For a shop simulation, a "customer" class with a generator in
Scriptic is:

class Customer {
  int birthtime;
public:
  static int n;
         int i;
  Customer(){i=n++;}

  scripts 
    Enter = {printf("customer %3u enters\n",i)}
    Leave = {printf("customer %3u leaves\n",i)}

    Live =     {birthtime=SimTime  }: Enter; GetServed(i);
          {qtime+=SimTime-birthtime}: Leave; {delete this}

   static scripts
     Poisson(t) = for(;;); {duration=RNDNEGEXP(t)}; {new Customer}->Live
};

...
scripts

  Day = Customer::Poisson(3) + HOURS(8) 
                        //  "+ HOURS(8)" kills script Poisson at closing time

This works fine. Note that I could not have taken a Customer constructor
in Day; I need a static member function for generating customers.

The problem arises when I want to generate other creatures as well
(thieves, mice, ...), WITHOUT reimplementing the static Poisson script for 
each kind of creature. (In Scriptic-C, without classes, this was possible
by passing a Customer script or something else as a parameter to a 
generic Poisson script: POISSON(3,Customer) ...)

In Scriptic-C++ I want to inherit from an abstract class, something like:

class Creature {
public:
  static int n;
         int i;
  Creature(){i=n++;}

  virtual scripts Live = 0;

   static scripts
     Poisson(t) = for(;;); {duration=RNDNEGEXP(t)}; {new this}->Live
};


class Customer: Creature {
  int birthtime;
public:
  scripts 
    Enter = {printf("customer %3u enters\n",i)}
    Leave = {printf("customer %3u leaves\n",i)}

    Live =     {birthtime=SimTime  }: Enter; GetServed(i);
          {qtime+=SimTime-birthtime}: Leave; {delete this}
};

class Thieve: Creature {
   ...
}

...
scripts

  Day = Customer::Poisson(3)
      + Thieve  ::Poisson(210)
      + Mouse   ::Poisson(120)
      + HOURS(8)


To summarize: I want the phrase "new this" permitted in static member
functions. I feel it would no be too hard to implement. Any comments?


Andre van Delft
DELFT@fwi.uva.nl