In other words "I want the egg of that chicken. I know that chicken hasn't laid that egg yet. However, since I know that chicken is going to lay that egg (trust me I know), let me have that egg now."
This is where forward declarations come into play.
I was brought here by something that came up while reading Pawel Glowacki's book Expert Delphi. I'm on page 233 from Chapter 7 - Sensing the world. Pawel discusses the TSensorManager class in the System.Sensors unit.
There is main TSensorManager class that acts as a gateway to all sensor information. It has a Current: TSensorManager class property that is used to reference all sensor information. At the top of the System.Sensors unit, you can find a TSensoryCategory enumerated type that provides the top level categorization of all possible sensors:
At this point my head was about to explode so I decided to open the System.Sensors unit and have a look at the actual code Pawel was referring to. Then it hit me.
What the hell is this empty class doing here? How can you have an empty class?
TSensorManager = class;I remember going down this empty class learning path a while ago. But do you think I can remember what it was, or means. No. Obviously, I had not associated a nice, simple "word picture" to the meaning of this empty class. Because if I had, I would have remembered.
So now I have the nice, easy to remember, "Oh that's Delphi's way of resolving the chicken or the egg thing" word picture.
Have a look at this type definition snippet from the System.Sensors unit:"
type // //other type declarations // TSensorManager = class; //←-- egg reference TCustomSensor = class abstract public type TProperty = (UniqueID, Manufacturer, Model, SerialNo, Name, Description); private FOnDataChanged: TNotifyEvent; FOnSensorRemoved: TNotifyEvent; FOnStateChanged: TNotifyEvent; FManager: TSensorManager; //←-- egg reference FStarted: Boolean; // // other class definitions // end; // //other type declarations // TSensorManager = class abstract //←--- chicken reference public type TFilters = TDictionary‹string tsensorfilter=""›; private class var FCurrentManager: TSensorManager; class function InternalGetSensorManager: TSensorManager; static; class constructor Create; class destructor Destroy; protected type TSensorManagerType = class of TSensorManager; // // other class definitions // end; // //other type declarations // implementationThe problem arises because there's a private field declaration in the TCustomerSensor class that references the TSensorManager class that doesn't exist yet. It's the damn "chicken or the egg" thing.
To get around this Delphi allows what is called a forward declaration.
This is not by any means the complete class definition. The complete class definition must be declared somewhere inside the same type declarations where the forward declaration resides.
Here are a couple useful links:
http://docwiki.embarcadero.com/RADStudio/Rio/en/Classes_and_Objects_(Delphi)#Forward_Declarations_and_Mutually_Dependent_Classes
http://www.delphibasics.co.uk/RTL.asp?Name=Class
Special Characters:
The "‹" and "›" in the source code sections were created using the Alt + Keypad method.
https://www.keynotesupport.com/websites/special-characters-symbols.shtml
Enjoy!
Semper Fi
Gunny Mike
https://zilchworks.com