Forward defined types (and object
Gale Paeper
gpaeper at empirenet.com
Fri Jul 8 04:27:24 CEST 2005
Frank Heckenbach wrote:
>
> Gale Paeper wrote:
>
[snip]
> > The forward object type declaration must have a complete type
> > declaration in the same type declaration part (like Pascal's requirement
> > for pointer types). The commented out var declaration part and type
> > keyword is what I used to test that requirement. Uncomment that part and
> > you get:
> >
> > Error : unresolved forward class reference to 'objA'
> > ForwardObjectTest.p line 11 var
>
> Good (in accordance with OOE, except for the syntax).
The other part of OOE's deferred class requirement (i.e., "cannot be
used in a class-inheritance-list before its complete definition is
specified") is also enforced. A slight modification of the test program
I've been using for an example:
program ForwardObjectTest1;
type
objA = object; forward;
objB = object
{...}
o : objA; { objB uses objA }
{...}
end;
{ WRONG - Can't inherit from a FORWARD declared object }
{ objC = object(objA)
end;
}
objA = object
{...}
p : objB; { objB uses objA }
{...}
end;
{ OK - Can inherit from a FORWARD object after it is fully defined }
objD = object(objA)
{ objD inherits from objA }
end;
begin
end.
With the objC type declaration commented out the program compiles
without error. Uncomment the objC type declaration and you get the
follow compilation error with CodeWarrior Pascal:
Error : class 'objA' was declared 'FORWARD' or 'EXTERNAL'
ForwardObjectTest1.p line 12 objC = object(objA)
For the sake of completeness and since the error message refers to
external object declarations, I suppose CodeWarrior Pascal and MPW
Pascal's support for external object declarations should be mentioned.
The basic purpose and reason for external object declaration is the same
as it is for forward declared objects except it is used for mutually
dependent object type declarations between unit interfaces.
Before an example program demonstrating the external object feature and
how it can be used, a few notes on this particular MacPascal Object
Pascal feature:
1. I'm not sure any real world program actually makes use of it.
2. Even Apple, who invented the feature for MPW Pascal, called code
using external objects "ugly" and the code, even though it maybe useful, confusing.
3. It isn't the easiest feature to make use of. It takes some thought
and care in organizing code to avoid circular unit interface dependency
errors and unresolved external object declaration errors.
So, there's no misunderstanding, I'm not asking for GPC's support for
MacPascal style objects to include external object declaration support.
Put it in the "to be considered if someone really needs it" bin. I'm
covering MacPascal external object declaration support so that Frank and
Waldek are at least aware of the feature and have an example of its usage.
The example program and units are:
program ExternalObjectTest;
uses UObjA, UObjB;
var
ObjAInstance: ObjA;
ObjBInstance: ObjB;
begin
ObjAInstance := NewObjA;
ObjBInstance := NewObjB;
ObjAInstance.InitwithObjB(ObjBInstance);
ObjBInstance.InitwithObjA(ObjAInstance);
ObjAInstance.TestObjAsObjBReference;
ObjBInstance.TestObjBsObjAReference;
Dispose(ObjAInstance);
Dispose(ObjBInstance);
end.
unit UObjA;
interface
type
ObjB = object; external;
ObjA = object
fObjB: ObjB;
procedure InitwithObjB(InitObj: ObjB);
procedure TestObjAsObjBReference;
procedure TestIt;
end;
function NewObjA: ObjA;
implementation
uses UObjB;
function NewObjA: ObjA;
var
obj: ObjA;
begin
new(obj);
NewObjA := obj;
end;
procedure ObjA.InitwithObjB(InitObj: ObjB);
begin
fObjB := InitObj;
end;
procedure ObjA.TestObjAsObjBReference;
begin
writeln ('In ObjA calling fObjB');
fObjB.TestIt;
end;
procedure ObjA.TestIt;
begin
writeln ('In ObjA TestIt');
end;
end.
unit UObjB;
interface
uses UObjA;
type
ObjA = object; external;
ObjB = object
fObjA: ObjA;
procedure InitwithObjA(InitObj: ObjA);
procedure TestObjBsObjAReference;
procedure TestIt;
end;
function NewObjB: ObjB;
implementation
function NewObjB: ObjB;
var
obj: ObjB;
begin
new(obj);
NewObjB := obj;
end;
procedure ObjB.InitwithObjA(InitObj: ObjA);
begin
fObjA := InitObj;
end;
procedure ObjB.TestObjBsObjAReference;
begin
writeln ('In ObjB calling fObjA');
fObjA.TestIt;
end;
procedure ObjB.TestIt;
begin
writeln ('In ObjB TestIt');
end;
end.
When compiled with CodeWarrior Pascal and subsequently ran, the program
output is:
In ObjA calling fObjB
In ObjB TestIt
In ObjB calling fObjA
In ObjA TestIt
Gale Paeper
gpaeper at empirenet.com
More information about the Gpc
mailing list