www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Class references, or using ClassInfo to instantiate classes?

reply "Vladimir Panteleev" <thecybershadow gmail.com> writes:
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" it=
self denotes a value whose type is class of "type". If type1 is an ances= tor of type2, then class of type2 is assignment-compatible with class of= type1. Thus
  type TClass =3D class of TObject;var AnyObj: TClass;
 declares a variable called AnyObj that can hold a reference to any cla=
ss. (The definition of a class-reference type cannot occur directly in a= variable declaration or parameter list.) You can assign the value nil t= o 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 uni= t):
  type TCollectionItemClass =3D class of TCollectionItem;     ...constr=
uctor 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 d= escending from Borland.VCL.Classes.TCollectionItem.
  Class-reference types are useful when you want to invoke a class meth=
od or virtual constructor on a class or object whose actual type is unkn= own at compile time.
  Constructors and Class References
  A constructor can be called using a variable of a class-reference typ=
e. This allows construction of objects whose type isn't known at compile= time. For example,
  type TControlClass =3D class of TControl;function CreateControl(Contr=
olClass: TControlClass; const ControlName: string; X, Y, W, H: Integer):= TControl;begin Result :=3D ControlClass.Create(MainForm); with = Result do begin Parent :=3D MainForm; Name :=3D Contr= olName; SetBounds(X, Y, W, H); Visible :=3D True; end= ;end;
 The CreateControl function requires a class-reference parameter to tel=
l it what kind of control to create. It uses this parameter to call the = class's constructor. Because class-type identifiers denote class-referen= ce values, a call to CreateControl can specify the identifier of the cla= ss 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 thi= s in D. The basic idea here is to allow inferior (in design layers) code to inst= antiate derived classes of which it does not know - but it could know th= at it is derived from a specific base type. The basic application of this is any kind of "object factory" class whic= h needs to be able to instantiate (and work with) different types of obj= ects. 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 f= unction in the ClassInfo type (proper return type and constructor argume= nts would need to be taken care of). Currently, the most straight-forward work-around is to pass a delegate f= unction which returns instances of your derived type as the base type th= e inferior code needs to work with. Also, this can de done with class te= mplates, but this would create a lot of repetitive code if "object facto= ries" for different types are required... -- = Best regards, Vladimir mailto:thecybershadow gmail.com
Feb 01 2007
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Vladimir Panteleev" <thecybershadow gmail.com> wrote in message 
news:op.tm2e1ndim02fvl cybershadow...

-------------------------------------
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.
-------------------------------------

This is possible with reflection.  Check out FlectioneD; it has (at least a 
limited form) of instantiating classes by a string name.  In fact, classes 
are represented by (gasp) the Class type. 
Feb 01 2007
parent reply "Vladimir Panteleev" <thecybershadow gmail.com> writes:
On Thu, 01 Feb 2007 17:21:14 +0200, Jarrett Billingsley <kb3ctd2 yahoo.com>
wrote:

 This is possible with reflection.  Check out FlectioneD; it has (at least a
 limited form) of instantiating classes by a string name.  In fact, classes
 are represented by (gasp) the Class type.
From what I understood, FlectioneD isn't really portable, and thus doesn't really compare to a language feature. Also, it requires debug symbols to be compiled in the executable, while this can be implemented as a fairly simple language construct... -- Best regards, Vladimir mailto:thecybershadow gmail.com
Feb 01 2007
next sibling parent "Denis Golovan" <denis azovprom.com> writes:
Vladimir Panteleev touched an interesting language feature. I thought D 
already has it.
Meta-class programming can be quite useful sometimes. So, add also my one 
voice
for such feature :)

Thanks. 
Feb 02 2007
prev sibling parent Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Vladimir Panteleev schrieb am 2007-02-02:
 On Thu, 01 Feb 2007 17:21:14 +0200, Jarrett Billingsley <kb3ctd2 yahoo.com>
wrote:

 This is possible with reflection.  Check out FlectioneD; it has (at least a
 limited form) of instantiating classes by a string name.  In fact, classes
 are represented by (gasp) the Class type.
From what I understood, FlectioneD isn't really portable, and thus doesn't really compare to a language feature. Also, it requires debug symbols to be compiled in the executable, while this can be implemented as a fairly simple language construct...
The problem is that oplink (the linker DMD uses on Windows) doesn't include the symtab information in the final binary. This isn't a limitation of the binary format but of the tools used. Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFFw1Y3LK5blCcjpWoRAvcsAJ9IlXdbAzWyciu3pCZSKQR1SdbkVQCeORE/ QVQ3qV+OsWtOmt/hHX2vY6A= =aH6m -----END PGP SIGNATURE-----
Feb 02 2007
prev sibling parent Nicolai Waniek <no.spam thank.you> writes:
Vladimir Panteleev wrote:
 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.
 
As a former Delphi developer myself, this would be a great feature-to-have!
Feb 05 2007