PDA

View Full Version : "class var" or "static" ?



chronozphere
27-07-2010, 03:57 PM
Hey guys

I learned java programming (because I had to, university) and one thing I really liked about the language is that you could create static variables and methods. These are not associated to individual objects but with the class as a whole.

Does someone know which version of Delphi (and up) supports this? And what about FPC?

I'd like to use this, but because I want to keep my code Delphi and FPC compatible, I'm not sure if this will be possible. Does anyone know more 'bout this?

Thanks :)

dazappa
27-07-2010, 04:35 PM
Hey guys

I learned java programming (because I had to, university) and one thing I really liked about the language is that you could create static variables and methods. These are not associated to individual objects but with the class as a whole.

Does someone know which version of Delphi (and up) supports this? And what about FPC?

I'd like to use this, but because I want to keep my code Delphi and FPC compatible, I'm not sure if this will be possible. Does anyone know more 'bout this?

Thanks :)

I'm slightly confused by your limited description, so I'll give you an example unit for demonstrating what I know and hope I cover what you desire:


unit Unit2;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils;

type
TMO = class
public
peach: integer;
procedure test();
private
pear: integer;
end;

var
orange: integer;

implementation

var
apple: integer;

procedure TMO.test();
begin
apple := 777;
orange := 888;
peach := 999;
pear := 000;
end;

end.

Now lets assume you have another unit (unit1) that uses unit2 and has an object of TMO.
unit2.apple is undefined; declaring it after implementation makes it local to unit2 only.
unit2.orange is global/public, so you can access it.
TMO.test(); sets the local variable apple, but unless you make a getter, you cannot access apple.
TMO.peach is public, so you can access it.
TMO.pear is private, so you cannot.

Now, I do have a limited java experience, but I never used static variables or methods, so I don't have much of a basis for what you are saying or meaning by "available to the whole class".

Based on my googling, it appears to be a global variable that is not reset upon each instantiation of a class, but instead keeps its value. Handy.

What you have to remember between pascal and java, is that in Pascal a unit is not an object. In java, a class is usually an object or contains multiple classes, so multiple objects.

In this case, I believe what you're looking for is the variable "apple" in my example; you set it, and every instance of TMO can access and change the same variable.

Also using FPC 2.2.X, if you couldn't guess by the {$mode objfpc}

JSoftware
27-07-2010, 06:54 PM
Class vars are supported in fpc trunk, I don't know how long back though. I guess it'll be supported back to 2.4.0

dazappa
27-07-2010, 08:55 PM
Class vars are supported in fpc trunk, I don't know how long back though. I guess it'll be supported back to 2.4.0

Interesting. I can't quite think of a reason I'd like to make a variable for one object only vs allowing all objects to access it, but I suppose it could help with organization. In any case, I guess unless you want to to download the trunk, having a private var in the unit would be the way to go. (Or you could test it yourself with current pub releases of FPC, of which I'm too lazy to look up the syntax to test on)

JSoftware
27-07-2010, 10:20 PM
Dazappa, it may not be obvious at first, if you've never needed it :)

Think of singletons before class vars. There was no easy way to do it, other than hardcode a global implementation section variable, like you suggested. Now you can make a rather elegant solution like this:


type
TSingletonClass = class of TSingleton;

TSingleton = class
private
class var fInstance: TSingleton;
public
class function GetInstance: TSingleton;

constructor Create; virtual;
destructor Destroy; override;
end;

TLaks = class(TSingleton)
hat: longint;
end;

class function TSingleton.GetInstance: TSingleton;
begin
if assigned(fInstance) then
result := fInstance
else
result := TSingletonClass(self.ClassType).Create;
end;

constructor TSingleton.Create;
begin
inherited Create;
fInstance := self;
end;

destructor TSingleton.Destroy;
begin
fInstance := nil;
inherited Destroy;
end;

var a,b: TLaks;
begin
a := TLaks(TLaks.GetInstance);
a.hat := 13421;

b := TLaks(TLaks.GetInstance);
writeln(b.hat);

a.free;
readln;
end.

User137
28-07-2010, 09:16 AM
This in my opinion goes in same page as c++ templates or operator overloading; optional, different way to program but overall makes code more complicated to understand. Some programmer in the future, some day will be confused on why object B property gets changed same time as object A property.

chronozphere
28-07-2010, 11:43 PM
Hah.. quite a lot of replies. :)

@Dazappa: Yes, excuse me for not explaining it very well. Like you have shown, declaring a new variable in the implementation section is also a good way (allthough less elegant) to make a class variable.



This in my opinion goes in same page as c++ templates or operator overloading; optional, different way to program but overall makes code more complicated to understand. Some programmer in the future, some day will be confused on why object B property gets changed same time as object A property.


I disagree. The concept of variables that are associated with a class is very easy to understand Easier that f.e Operator overloading and templates. I agree that those two can make your program harder to read and understand. Still I feel that static/class variables offer a really elegant solution to a number of problems (Singleton being one of them).
And ofcourse, everyone should learn how to use a language properly. Pascal supports a lot of features that can be used to make confusing source-code. In the end, it's all about how you use the tools that are offered to you.

It makes sense to associate certain data with a class. Let's say you have a class that loads a certain image format. It would be perfectly sane to make an class constant that contains the extension of the image that can be loaded with that class. You could derive a lot of classes for a lot of formats, each having their own extension in a class const.

Java requires another way of thinking. You are forced to organize everything into classes. While this may seem annoying, it makes you think about other and better ways to construct your programs. Static variables and methods were a real eye-opener for me. I would like to use them in my pascal programs aswell.

I'd like to know which version of delphi and FPC supports this (FPC 2.4.0 was mentioned).
Also, are the FPC and Delphi implementations of class var/class const compatible?

Thanks

User137
04-08-2010, 06:33 AM
1 thing more to add... Other way of getting functionality same as class constants is public/private functions. Possibly also virtual or overriden from subclasses.

type
TMyClass = class
public
A: string;
constructor Create;
function B: string;
end;

implementation

constructor TMyClass.Create;
begin
inherited Create;
A := 'A';
end;

function TMyClass.B: string;
begin
result := 'B';
end;