Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

unit to unit referencing of public variables

Status
Not open for further replies.

Han777

Programmer
Dec 12, 2007
19
As a professional trading system developer writing Delphi dll for NeoTicker, I've recently advanced from procedural to Object Oriented Programming and am having trouble referencing across units.

If in Delphi unit1 a procedure of a class named Dad assigns a value to its public variable DadsVar, and a procedure in unit2 creates an instance of Dad, how does an unrelated procedure in unit3 correctly reference Unit2's instance of that public variable, DadsVar, in unit2's instance of Dad?

Would it be Unit2.Dad.DadsVar That doesn't seem to work for me.
 
The actual code among these units is 100s of lines of proprietary trading system code. I would have to recreate a skeletal dll. Is this adequate clarification:

Unit1;
USES
...

TYPE
Dad = class
Protected
...[other variables]
Public
LooseChange : integer;
constructor.create; virtual;
procedure calc; virtual;
...
end;

Implementation
...

_____________ end of unit 1 __________________
Unit2
USES
...
Unit1;

TYPE
Kid = class(Dad)
constructor create; override;
procedure calc; override;
end;

IMPLEMENTATION
var
Daddy : Dad;

constructor Kid.create;

procedure Kid.calc;
Daddy.calc
// If the Kid wants to spend 3 of Daddy's $10 what code would the Kid
// place here to assign $7 to Daddy's LooseChange and not to the Kid's
// inherited LooseChange?
end;
_____________ end of unit 2 __________________
Unit3
USES
...
Unit2;

TYPE
brother = class
constructor create; override;
procedure calc; override;
end;

IMPLEMENTATION
var
i : integer;
brother.calc
// How would the brother here reference the Loosechange in unit2's instance of
// Daddy, without referencing the Kid's inherited LooseChange or his own inherited LooseChange?
end;

 
You need to move the variable declaration of Daddy in unit two into the interface section - it's not visible as it is in the implementation section.

Then, in unit 3, you can reference Daddy.LooseChange
 
I think the problem is more fundamental than the question you asked. You're creating classes from scratch (where's TObject?), your class hierarchy is confused (why must you override every method?), you access properties from an unrelated object thus breaking encapsulation, and you seem to think that by creating a subclass you get instances of the subclass and its parent. The transition to OOP is rocky.

A few weeks ago, lespaul found and recommended a wonderful, free, online book:
It isn't a beginning programming book, it's for Delphi programmers who want to learn OOP. It's not your typical twaddle trying to relate some taxonomy like "animal--mammal--cat" to classes and inheritance. Instead it starts with something real that you already know: the Delphi VCL.

Spend some time at least with the first three parts, because whatever you have been using isn't working. You'll be glad you did.
 
thanks for that recognition....it's a great book, and really helped me understand more about OOP in general and in Delphi specifically. Too bad I'm moving to Java (which the general OOP knowledge WILL help), but we won't be doing much Delphi development in the future. [sad]


Leslie

In an open world there's no need for windows and gates
 
Thanks to Griffyn and Harebrain for a timely response to my first post in this newfound forum. Its a privilege to immediately hear from a couple of the top 10 MVPs. That quality of knowledgeable support can saves days of perplexity and is immensely valuable to me in my transition to OOP.

Not wanting to compromise the cherished privilege of your so freely sharing hard-earned knowledge, nor taint what satisfaction you find in sharing it with sincere peers, I'm quick to listen and slow to correct willing mentors, but would like to ask a few questions and admit to the rationale (likely born of some misconceptions) for the code I submitted, with the hope of improving on my approach and discerning those misconceptions. My fear is that you might incorrectly suppose I know more than I do or that I'm a "know it all." My command of OOP is definitely in need of more knowledgeable programmers' observations and I'm hoping you will see in my detailed response a sincere desire to discover my foibles, without failing to clarify what I already know so I can benefit from your willingness to help me understand what I don't.

Please be assured I'm not lazy about doing my homework and consulting my copies of Mastering Borland Delphi 2005, Delphi in a Nutshell, Delphi TroubleShooting, Delphi Proamming for Dummies and my purchased hard disk version of DelphiBasics and have visited delphi.about.com many times in search of answers. I suspect I am needing more appreciation of the principles of encapsulation but wonder how best to practically apply them to trading system development of dlls. Though it might seem a little long winded, since this thread is our first occassion to get acquainted and for you to appraise my knowledge-level in the light of what I've thus far, perhaps mistakenly, supposed is a safe way to develop a multiple-setup trading system, I hope you'll allow me to address your responses with a little more detail than forum etiquette would smile upon.

RE. Griffyn's suggestion
IF I understand correctly, your are suggesting that I make the instance of Daddy global by declaring it in the interface section. I'm reluctant to create very many global variables because my trading system will have hundreds of variables. The less I make globals, the less likely I am to create a new setup that inadvertently references and changes the value of some other setups global variables, with very similar names, thinking it relates to the new setup.

Some trading system developers use lots of globals because its so easy and useful to manipulate useful output other indicators have produced, and since all they are doing is writing a dll to interface to a specific trading platform like NeoTicker it may not be as hazardous as when writing full-blown applications that may expose themselves to lots of units, but I'm trying to minimize risks without giving up the convenience of referencing non-global, unrelated public variables created in an object instantiated in another unit.

I need for example to create a record in an instance of a class that an instantiated subclass of that parent class's instantiation also writes to. Specifically, I currently have a swinghighs unit that creates and writes to a variable declared as swingtips : array of record, which bar by bar adds records of swinghighs to the array, and I have a subclass of the swinghigh class named swinglows that needs to also add records to the same array of records. I'll need to reference records in that array by yet another class in another unit, which is related to neither of the swinghighs or swinglows classes.

Am I wrong in supposing that the public variables of a class instantiated in the procedure of some other instantiated class can be referenced by both related and unrelated procedures in yet another class in some other unit? That is effectively what my simple abbreviated example intended to illustrate. Unit1 would be the swinghigh class, Unit2 would be the swinglow class, Unit three would instantiate both of them, and unit 2 and 3 would both reference the variable array of records instantiated by Unit1.

Response to harebrains suggestions.

RE TObject, isn't it the default class and therefore doesn't need to be cited, or are their occassions when its necessary?

RE. use of override, my example is a simplification of a trading model that uses the same general code for buying as it does for selling. When I create the code for buying I then create a subclass with overridden constructor and procedure so I can set different variable values with the overridden constructor and modify the overridden procedure based on whether I'm managing a buy or sell. What I would like to learn to do, if its possible is to only write one code block for a trade object that would both buy and sell, accomplished by sending a string parameter of "buy" or "sell" to the trade object that could be concatenated with strings in the trade object like "market(...)" to create executable trade commands like "buymarket(...)" or "sellmarket(...)" The buy and sell commands are much longer than what I've listed but identical except for the buy or sell . I know I could write two lines of code whereever needed in the trade object and allow an IF statement to control which one executed but wouldn't it be a lot less coding if I developed a protocol to concatenate what I need into commands. This combined with a passed variable that is either plus 1 or minus 1 depending on whether buying or selling could be used to switch the +- of numbers needing to be switched in the trade object when selling instead of buying.

As I write many customized trade objects depending on how the trade should be managed, I could escape the need to code an overridden sell subclass for every buy class. Now if I modify the buy instructions I need to go to the sell object and make corresponding changes. Longterm it could save me many hours and minimize error.

So, is it possible with Delphi to take a passed string parameter and combine it with strings that represent what is common to both buying and selling commands, then turn that string concatenation into an executable command, that is a line of executable line of code instead of a long string that doesn't do anything?

RE encapsulation
In light of what I shared above, how can improve on encapsulation without giving up the practical convenience of referencing public variables, without making them vulnerable to the risk of being universally global. Again, am I wrong about being able to reference and modify the value of a public variable of an unrelated object not instantiated in the interface section, as Daddy was not in unit2? What is a better way to get the job done without accessing "properties from an unrelated object thus breaking encapsulation" as you suggested.

I can see why you inferred I thought I was creating more instances than my example shows, but, with apologies, my unexplained assumption was that Unit1 and Unit2 had both been instantiated by Unit3 and that Unit 2 and 3 could see the value of their public variables. Is that true?

Thank you both, and any others, for answering these questions. If I'm not wrong about it being possible to reference unit1's loosechange once instances of all three units' classes exist, how in unit2 and unit3 would it be done? If I am need to be advised of a misconception I will be most grateful.

All the best,

Han777

 
assumption was that Unit1 and Unit2 had both been instantiated by Unit3
Then Unit3 must have reference variables of type Dad and Kid, which would be given values when the objects were instantiated:
Code:
unit Unit3
  .
  .
  .
implementation 

var
  objDad: Dad;
  objKid: Kid;
  .
  .
  .
{ perhaps in the initialization section }
  objDad := Dad.Create;
  objKid := Kid.Create;
  .
  .
  .
Now, in Unit3, you can access the public data members of the objDad and objKid instances through the objects' reference variable, e.g., objDad.LooseChange and objKid.LooseChange. objKid inherits LooseChange from Dad; Kid does not have his own LooseChange; objects that are instances of the Kid class inherit the LooseChange public data member from the Dad class. They are differentiated by which reference variable you use.

These object instances are not visible outside Unit3: they belong to Unit3's implementation. Anything you wish to expose from the Brother class must be part of Brother's public interface. If Brother had a LooseChange public data member, then you could assign objKid.LooseChange (or objDad.LooseChange) to it somewhere in Unit3's implementation and another class that had instantiated a Brother object would have access to it.

Is this helping?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top