Topic: Interest of static constructors, semantics, examples


Author: Philippe Verdy <100105.3120@compuserve.com>
Date: 1996/04/03
Raw View
I should first state the semantic and rules of static
constructor before proceeding further with static inheritance

- If a class defines a static constructor, its static members
  must not be initialized. Only the whole class can be
  initialized with the following syntax:
  static class X;
    // uses the static default constructor
  or:
  static class X(parameters);
    // uses a parameterized static constructor.
    // Optionally supported, because it adds syntax conflicts
  or:
  static (class X(parameters));
    // to solve the ambiguities

- A static constructor initialize its static members the
  same way an instance constructor calls the constructors
  for each of their non-static members:
  static X::X()
    : static_member1(value1)
    , static_member2(value2)
  {
    // additional code
  };

- All static members not described in this list must have
  a default constructor defined, which will be implicitly
  called in declaration order after each explicit call of
  static member constructors.

- A static constructor can call the standard constructor
  of a class from which it derives statically:
  class Y { ... };
  class X : static Y
  {
    static X()
      : Y() // calls the standard instance constructor of Y
      , classmember1(value1)
    { ... }
    X() {...} // standard default constructor for instances
  };

- If a static base class Y (we will call it a metaclass) is
  not initialized by calling one of its constructors from the
  static constructor of the class, the metaclass Y must have
  a default constructor which will be called implicitly
  in the order of declaration of the metaclasses, but after
  the other explicit metaclass constructions

- The static members and metaclasses destructors will be
  implicitly called in the reverse order of the calls of
  constructors.

- There should only be one static constructor for any class,
  because this class construction will occur only once for
  the whole application.

- Classes may have static base classes, called metaclasses,
  in addition to their static members. This means that the
  class inherits statically of a unique instance of its
  metaclass. The methods which apply on instances of these
  base classes will apply to the class itself, even without
  specifying any of its instances.
  The access rules (public, protected, private) for these
  inherited properties (attributes and methods) are the same
  as for standard (non-static) base classes properties.
  Without its additional methods and members, the class
  can be seen as a static variable, constructed with the
  code implemented in the static constructor.

- Multiple static inheritance is possible. In fact, its like
  if we built an anonymous class which inherits non statically
  from the same bases, and used it to build a classic (but
  anonymous) instance, which properties would be fully
  accessible within our class. The rules for the construction
  of this instance are the same as the rule of constuction
  of a static instance of a standard class which has multiple
  inheritance.

- static virtual inheritance is implied for the same reasons.
  This is to solve the conflicts which come from multiple
  inheritance, the same way we did for non-static inheritance.

- static functions can be made virtual. This will most often
  occur if one of the static base classes define non-static
  virtual methods, so that we can override them within our
  class, while being able to call them directly from the
  base class.

- There is no problem of multiple base class constructions,
  because we don't call directly the static base class
  constructor. Instead, the compiler generates at run-time
  a virtual table by using a flag in each class vtable which
  will also be used to chain the classes constructed, so that
  destructors are called in the appropriate order.

Now here are the interest of static constructors:

- You can create a metaclass/class hierarchy which fixes the
  order of construction of each classes.
- You can use multiple inheritance of containers to create
  custom class registration with much more power than RTTI.
- Using this feature, you avoid most of templates, and
  still have more compact code, while allowing for dynamic
  registration of classes at run-time (for example when
  loading additional classes from a dynamically loaded DLL
  or driver). We can use virtual static function pointers as
  arguments to the constructors of static baseclasses.

Example:

class RegisterClass {
public:
  class MyClass {
  public:
    MyClass(RegisterClass *cl, const char *name) {
      C = cl;
      N = nm;
    }
    RegisterClass *C;
    char          *N;
  }

  RegisterClass(char *name)
  {
    reg.insert(new MyClass(this, name));
  }

private:
  static Array<MyClass * const> reg;
}

class Y : virtual static RegisterClass
{
  static Y()
  : RegisterClass("Y")
  {
    // some code to do with constructed static members of Y
    // make Y usable to create instances
  };
  ...
}

class X : Y, virtual static RegisterClass
{
  static X()
  : Y
  , RegisterClass("X")
  , BaseClass("Y")
  {
    // some code to do with constructed static members of X
    // make X usable to create instances
  }
  ...
}

class Z : virtual X, virtual Y, virtual static RegisterClass
{
  static Z()
  : X(), Y()
  , RegisterClass("Z")
  , BaseClass("X")
  , BaseClass("Y")
  {
    // some code to do with constructed static members of Z
    // make Z usable to create instances
  }
  ...
}

-
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Etay Bogner" <etay@vocaltec.com>
Date: 1996/04/03
Raw View
Philippe,

I think that the only reason for your suggestion is to have a unified
system for registering classes at runtime, and you are wrapping this reason
with the "Metaclass" label.

The features you want can be programmed by another langauge feature,
templates.
Such a template system *can* be built.

Etay.


---------------------------------------------------
This message was created and sent using the Cyberdog Mail System
---------------------------------------------------
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]