Object Binding
Object reference variables, (defined using the keyword "dynamic"), in WinDev 7.5 have an object class bound to them at runtime (with one exception). That is, the class of the object they refer to is not determined from the object, but is stored with the object reference variable itself. The class storage is done at the time the variable is assigned. For example:
ObjRef is MyClass dynamic ObjRef = SomeChildObjectRef // ObjRef is a reference to MyClass regardless of the class of SomeChildObjectRef
The assignment must, of course, pass static binding rules to pass compilation. That is, MyClass must be the same as, or parent class of, the class of SomeChildObjectRef.
The only exception to the above rule is when a reference variable has a defined type of "object" which will always receive the type of the object assigned to it. For example:
ObjRef is object dynamic ObjRef = SomeChildObjectRef // ObjRef is a reference to the class of SomeChildObjectRef
However, the class of object when you use the predefined variable "object", is the class in which "object" is being used. For example:
PROCEDURE Tree::AddChild(Child) Child:Parent = object // Child:Parent will always a refer to the current class (Tree), not the class of the calling object (the invoker of AddChild)
This makes it difficult to link derived class objects together via a parent class library.
Approaches:
A. Use of the "object" Variable
The "object" variable, (as opposed to variables of type "object") fixes the class of an object reference to the class in which the "object" variable is being used. A solution to this is to create a base class from which all other classes MUST be derived, and to insist that a virtual function called "Self" be defined for every class in the following fashion:
Obj is class // The base class of all objects END PROCEDURE Self() Tmp is Obj dynamic = object // Must be defined for all derived classes and substitue "YourClass" for "Obj" RESULT Tmp
B. Object assignment:
Reference variables that could refer to different class (regardless of being derived classes) need to be defined as of type object dynamic.
For example, instead of:
LinkList is class Next Is LinkList dynamic END
LinkListDerivative is class object LinkList // a derived class of LinkList SomeData is string // some data for storage END
Tmp1 is LinkListDerivative dynamic = new LinkListDerivative // Make one Tmp2 is LinkListDerivative dynamic = new LinkListDerivative // Make another TmpResult is LinkListDerivative dynamic // Result
Tmp1:Next = Tmp2 // Tmp2 is a LinkList derivative so can be store here TmpResult = Tmp1:Next // *** RUNTIME ERROR *** Tmp2 is now a LinkList type
The following works:
LinkList is class Next Is object dynamic // use anonymous reference END
LinkListDerivative is class object LinkList // a derived class of LinkList SomeData is string // some data for storage END
Tmp1 is LinkListDerivative dynamic = new LinkListDerivative // Make one Tmp2 is LinkListDerivative dynamic = new LinkListDerivative // Make another TmpResult is LinkListDerivative dynamic // Result
Tmp1:Next = Tmp2 // Next is anonymous storage so can be store here TmpResult = Tmp1:Next // *** OK *** TmpResult resets class to LinkListDerivative |