tags:

views:

121

answers:

2

Comming from a C# background I'm trying to learn Delphi. I encounter an Access violation when in my form I press a button that creates a TLight instance. Wherever I try to access my private FState I get an access violation.

What am I missing?

unit Light;
interface
uses sysUtils;

type
  TLightStates = (Red, Orange, Green);
type
  TLight = class
    private
      Fstate : TLightStates;
    published
      Constructor Create(); overload;
      procedure SetState(const Value: TLightStates);
      Property State : TLightStates
        read Fstate
        write SetState;
  end;

implementation
{ TLight }
    constructor TLight.Create;
    begin
      Fstate := TLightStates.Red;
    end;

    procedure TLight.SetState(const Value: TLightStates);
    begin
      Fstate := Value;
    end;
end.
+3  A: 

Did you create an object in your test code where the property State is set?

var
  x: TLight;
begin
  x := TLight.Create;
  x.Light := Orange;
  x.Free; 
end;

Looking at the code this should work correctly.

One other thing: why did you specify the contructor with overload: you derive from TObject and it does not have a virtual constructor, so overload should not be specified here.

Ritsaert Hornstra
Aha, I didn't initialize it as in C# enums don't need to be created. The reason I'm overriding is because I saw it like that in the tutorial ;) I see now this is rather pointless. Thx
borisCallens
@Ritsaert - you actually meant override instead of overload; override causes syntax error when applied to non-virtual methods; overload can be applyed to any method, it is just pointless here.
Serg
>I didn't initialize it as in C# enums don't need to be created.delphi enums don't need to be instantiated either. in C# you can declare an object so it'll be created (and destroyed) automatically. regrettably, delphi doesn't have this.
X-Ray
@Serg: oops you're right. I just mispelled it in my head..
Ritsaert Hornstra
+2  A: 

One comment about the above piece of code :

var
  x: TLight;
begin
  x := TLight.Create;
  TRY  
    x.Light := Orange;
  FINALLY
    x.Free; 
  END;
end;

"try" and "finally" (uppercase used above for readability) ensure that x will be freed. As you might know by now, there is no garbage collection in Delphi so freeing your objects is a must...

About your initial piece of code : Your create should be virtual and public. Minor comments :

  1. TLightStates = (Red, Orange, Green) should actually be TLightState = (Red, Orange, Green) (no "s" since adding an "s" would usually mean a set of TLightState)
  2. Your SetState procedure should ideally be protected instead of published.

hth, kuzkot

kuzkot
There is absolutely no need to declare Create as a virtual constructor - that is at least pointless.
Serg
-1. Does not answer the question, and is overly pedantic about code that's really just fine. Please use *comments* for things that aren't related to the question at hand. (You'll be allowed to post comments once you earn just a little more reputation points.) Welcome to Stack Overflow.
Rob Kennedy
Agreed that this should have been a comment. But "overly pedantic"? I see some valid points - try-finally, enum naming convention, not making setters published.
Ulrich Gerhardt