Class references, or using ClassInfo to instantiate classes?

Vladimir Panteleev thecybershadow at gmail.com
Thu Feb 1 02:21:13 PST 2007


Dear Newsgroup,

Delphi has one outstanding feature it calls "class references".
Basically, these are data types which allow you to work with class types - instantiate them, get the class type of their base (super) class, etc.

Quoting the Delphi manual on the topic:

> Class-Reference Types
> A class-reference type, sometimes called a metaclass, is denoted by a construction of the form
>  class of typewhere "type" is any class type. The identifier "type" itself denotes a value whose type is class of "type". If type1 is an ancestor of type2, then class of type2 is assignment-compatible with class of type1. Thus
>  type TClass = class of TObject;var AnyObj: TClass;
> declares a variable called AnyObj that can hold a reference to any class. (The definition of a class-reference type cannot occur directly in a variable declaration or parameter list.) You can assign the value nil to a variable of any class-reference type.
>  To see how class-reference types are used, look at the declaration of the constructor for Borland.VCL.Classes.TCollection (in the Classes unit):
>  type TCollectionItemClass = class of TCollectionItem;     ...constructor Create(ItemClass: TCollectionItemClass);
> This declaration says that to create a Borland.VCL.Classes.TCollection instance object, you must pass to the constructor the name of a class descending from Borland.VCL.Classes.TCollectionItem.
>  Class-reference types are useful when you want to invoke a class method or virtual constructor on a class or object whose actual type is unknown at compile time.
>  Constructors and Class References
>  A constructor can be called using a variable of a class-reference type. This allows construction of objects whose type isn't known at compile time. For example,
>  type TControlClass = class of TControl;function CreateControl(ControlClass: TControlClass; const ControlName: string; X, Y, W, H: Integer): TControl;begin     Result := ControlClass.Create(MainForm);     with Result do      begin        Parent := MainForm;        Name := ControlName;        SetBounds(X, Y, W, H);        Visible := True;      end;end;
> The CreateControl function requires a class-reference parameter to tell it what kind of control to create. It uses this parameter to call the class's constructor. Because class-type identifiers denote class-reference values, a call to CreateControl can specify the identifier of the class to create an instance of. For example,
>  CreateControl(TEdit, 'Edit1', 10, 10, 100, 20);

Coming from Delphi myself, I would really love to see something like this in D.

The basic idea here is to allow inferior (in design layers) code to instantiate derived classes of which it does not know - but it could know that it is derived from a specific base type.

The basic application of this is any kind of "object factory" class which needs to be able to instantiate (and work with) different types of objects.

Implemented, this type would need just the details required to construct the object - the pointer to the constructor, and to the VMT (if the VMT pointer isn't set by the constructor).

I'm not sure if this can be implemented something like an .instantiate function in the ClassInfo type (proper return type and constructor arguments would need to be taken care of).

Currently, the most straight-forward work-around is to pass a delegate function which returns instances of your derived type as the base type the inferior code needs to work with. Also, this can de done with class templates, but this would create a lot of repetitive code if "object factories" for different types are required...

-- 
Best regards,
  Vladimir                          mailto:thecybershadow at gmail.com



More information about the Digitalmars-d mailing list