On 30 May 10, at 04:00 , spir ☣ wrote:

> So, it seems the language knows (at runtime) about the real type of a 
> *value*. I must declare element, the variable, with type C, since I do not 
> know anything at coding time. But Pascal correctly calls C1.text, due to 
> "virtual" & "override" modifiers. So, it means that the language has 
> additional type information and uses it to make a distinction between 
> variable and value types. Correct? Else, how can it correctly call C1.text?

Correct.  Each object instance has a pointer to a structure which defines its 
class - inheritance, TypeInfo, VMT (virtual method table), etc.  This allows 
the application access to everything about the instance variable at runtime.  
Suggest reading the Class Types section of the Programmers Manual and anything 
related to Classes, VMT or TypeInfo in the Programmers, Run-Time Library and 
Language Reference Manuals.

> But I'm not 100% sure this means that, for Pascal and at runtime, element's 
> value is of type C1. Is there a way to know value and/or variable's types, 
> such as a func TypeName()?

All classes are derived from TObject which has many useful methods - including 
Classname, ClassnameIs(), ClassType and InheritsFrom().  It would be worth 
reading the TObject section of the Run-Time Library Manual.

> (Side-note: I do not understand why this overriding mechanism needs to be 
> explicitely stated with a modifier keyword: when a programmer writes a 
> specialised method on a sub-class, obviously s/he intends it to be called, 
> no?)

Not necessarily.  Choosing between Static/Virtual allows the class designer to 
determine what aspects of the ancestor class behaviour can be modified in a 
descendent - and therefore protect the ancestor function from being 
accidentally or purposefully broken.  Usually only a few methods of a class 
need to be virtual.

In Delphi and FPC all methods are static by default (this is distinctly 
different from many other languages where methods are always virtual).  Static 
methods execute faster as the VMT does not need to be accessed, and they can be 
called against a nil object.  Static methods also allow parameters to vary 
between classes (this constraint can be very annoying in languages where all 
methods are virtual and overloading is not supported).  Understanding the 
difference between static and virtual method behaviour is key to OO programming 
- especially if you are using polymorphism as you are in your example program - 
suggest reading more on this topic in the Programmers and Language Reference 
Manuals.

> Can I rely on this mechanism to correctly dispatch method calls in any case, 
> by building a system such as:
> * All values are class instances.
> * They have a unique ancestor class C, on which all possibly overridable 
> methods are declared virtual.
> * On sub-classes, all methods existing on the ancestor(s) are explicitely 
> declared override.
> Then, whatever the class of a variable or of its value for Pascal, the 
> correct method will be called?
> If yes, as I think now, this is a very constructive point :-)

Yes.

> Another one would be to acually know a value's type. How to get its name or, 
> much better, a pointer to it? (Since the language obviously has such a 
> pointer.)

aObj.ClassType will return the TClass of the object.  If you refer to the 
Manuals as suggested above you will find how to access the TypeInfo for a 
class.  Note - you can also variably instantiate an object at runtime by 
working with the TClass...  extending your code example:

type
  TMyCClass = class of C;

function CreateTheCorrectObjectAtRunTime(aC: TMyCClass): C; 
begin
  result := aC.Create;
end;

The result maybe C or any descendent of C (C1, C2, C21, etc) depending on what 
classtype is passed to the function.  This feature may require that your 
constructor is virtual so that the compiler can determine the correct 
constructor to call at runtime (this is why TComponent's constructor is virtual 
as this behaviour is fundamental to TFiler/TReader and streaming components.  
If aC had been the base type TClass this code would work as well - however 
creating your own class types allows for more robust code and mean you can 
implement without casting variables - especially useful if your constructor is 
not virtual, and/or constructor parameters vary between your classes.  If you 
are interested in this area, Chapter 6 Classes in the Language Reference Manual 
is worth a read...

Regards

Andrew._______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to