0

I have two classes, a child class:

type MyChildClass = class
public
parent: ^MyParent;
end;

And a parent class:

type MyParentClass = class
public
childs: array of ^MyChildClass;
end;

However, this wont work since only the class declared the last knows the other one. Example:

program Test;

interface

type MyChildClass = class
public
parent: ^MyParentClass;
end;

type MyParentClass = class
public
childs: array of ^MyChildClass;
end;

implementation

end.

This wont compile because the 7th line will throw the error "Undeclared identifier 'MyParentClass' as expected. Using abstract classes only solves the problem partially. Im really struggling on finding a solution. Maybe using interfaces would help?

  • 3
    [Forward declaration](http://docwiki.embarcadero.com/RADStudio/en/Classes_and_Objects_(Delphi)#Forward_Declarations_and_Mutually_Dependent_Classes) is what you're missing. Except that, you can declare those field types not like pointers (by removing those `^` operators). And we're using `T` prefix for `T`ype declarations. – Victoria Aug 26 '18 at 17:23
  • Thanks a lot! That was it! –  Aug 26 '18 at 17:27
  • You're welcome! – Victoria Aug 26 '18 at 17:27
  • 1
    FWIW, do not use pointer syntax for parent or children. In Delphi, class instance variables are references already. More about this in my article about pointers (and references): [Addressing pointers -- References](http://rvelthuis.de/articles/articles-pointers.html#references). – Rudy Velthuis Aug 26 '18 at 17:38
  • @rudy I know that the extra level of indirection isn't likely to be correct here, and is likely based on a misunderstanding. But it isn't too hard to construct scenarios where pointer to reference makes sense. So perhaps a less absolute instruction would be preferable. – David Heffernan Aug 27 '18 at 07:28
  • 1
    @David: I meant in this situation, hence the mention of parent and children. So I think what I wrote is correct. – Rudy Velthuis Aug 27 '18 at 07:37
  • @rudy With that clarification it is reasonable advice. – David Heffernan Aug 27 '18 at 07:38
  • @David: well thank you! – Rudy Velthuis Aug 27 '18 at 08:09

2 Answers2

3

Pascal is a single pass-compiled language, therefore the compiler scans only once a single file: in every moment it has to know each identifier. When you are creating a circular reference, like in this case, you are referencing a class written after the current one which is not permitted. To fix this issue, you need to use the so called forward declaration, i.e. you are declaring (promising) to the compiler that somewhere in your code it will find this identifer (look at the code, problem1).

Additionally, you are defining multiple different type scopes (by writing type multiple times). Each type scope has it's own types (and a type defined in a scope cannot be seen by another scope), hence, you need to define a single one (look at the code, problem2).

program Test;

interface

type // declare a single type scope (problem 2)
    MyParentClass = class; // this is the forward declaration (problem 1)

    MyChildClass = class
    public
        parent: ^MyParentClass;
    end;

    MyParentClass = class
    public
        childs: array of ^MyChildClass;
    end;

implementation

end.
Yennefer
  • 5,704
  • 7
  • 31
  • 44
-1
program Test;

interface
type 
    MyParentClass = class;

    MyChildClass = class
    public
        parent: ^MyParentClass;
    end;

    MyParentClass = class
    public
        childs: array of ^MyChildClass;
    end;

implementation

end.
MSB
  • 181
  • 1
  • 2
  • 9