Recent

Author Topic: [SOLVED] OOP and FPC  (Read 24461 times)

Pascaluvr

  • Full Member
  • ***
  • Posts: 216
Re: OOP and FPC
« Reply #15 on: March 20, 2012, 12:46:15 am »
Ok, heres my code - still crahing with SIGSEGV when I try to close the form:
LLtest
Code: [Select]
unit LLtest;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ComCtrls,
  LinkedList;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Memo1: TMemo;
    StatusBar1: TStatusBar;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  LL:    tLinkedList;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
  begin
  LL.Free;
  Button1.Visible := False;
  Button3.Visible := True;
  ShowMessage('Class freed');
//  Form1.Close;
  end;

procedure TForm1.Button2Click(Sender: TObject);
  var
    w:         string = 'Test String';
  begin
  LL.AddItem(@w[1]);
  ShowMessage('ItemCount now: ' + IntToStr(LL.ItemCount) +
               ' ItemSize is: ' + IntToStr(LL.ItemSize));
  end;

procedure TForm1.Button3Click(Sender: TObject);
begin
//LL.Create(100);
  LL := tLinkedList.Create(100);
  Button3.Visible := False;
  Button1.Visible := True;
  ShowMessage('LL Created');
end;


end.

and my Class unit:
Code: [Select]
unit LinkedList;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, cmem;

Type
  ItemRec = Record
    Prev,
    Next:                 Pointer;
    Item:                 array of char;
  end;

  tLinkedList = Class
      First,
      Last,
      Curr:                 ^ItemRec;
      ItemCount:            LongInt;
      ItemSize:             LongInt;
      Constructor Create(s: LongInt);
      Destructor Free;
      Procedure AddItem(Item: Pointer);

  end;


implementation

Constructor tLinkedList.Create(s: LongInt);
  begin
  First := Nil;           // I think I read somewhere that
  Last := Nil;            // variables in classes are auto-init
  Curr := nil;            // but I want to be sure
  ItemCount := 0;
  ItemSize := s;
  end;

Destructor tLinkedList.Free();
  begin
  if first = nil then exit;
  // Free the entries here
  end;

Procedure tLinkedList.AddItem(Item: Pointer);
  begin
  Inc(ItemCount);
  // Build the linked list
  end;

end.
Windows 7, Lazarus 1.0.8, FPC 2.6.2, SQLite 3

CaptBill

  • Sr. Member
  • ****
  • Posts: 435
Re: OOP and FPC
« Reply #16 on: March 20, 2012, 01:12:59 am »
Aha!

It is probably because you named your destructor as tlinkedlist.free

'Free' is a reserved word. This global method is for freeing objects, not classes. It's more of a generic method that applies to object variables. Your class has it's own destructor, or a custom version of 'free'.This is a naming convention mixup is all. Always use the naming convention for destructors...  'destroy'.

This brings up another very important step to help with OOP... study the naming conventions carefully and use them. They convey lot's of info/clues as to what each element is for, and where in the hierachy things belong/come from. They help you to see the structural importance of the elements etc.

In fact you should be able to call the stock object freeing method 'free' anyway, if I am not mistaken, as an alternate method.
So you are having a clash here with the generic 'free' method, confusing the compiler

tLinkedList.free (//after you rename your destroctor to tLinkedList.destroy)

or...

tLinkedList.destroy (//this is your class destructor)

« Last Edit: March 20, 2012, 01:26:37 am by CaptBill »

CaptBill

  • Sr. Member
  • ****
  • Posts: 435
Re: OOP and FPC
« Reply #17 on: March 20, 2012, 01:51:15 am »
So your class with naming conventions will look like:


Code: [Select]
  tLinkedList = Class

   private                                      //only the class itself should access these variables or 'private'

      fFirst,                                      // 'f' prefix to show this is a 'field'   
      fLast,
      fCurr:                 ^ItemRec;

   public                                       //this section is visible to the outside world

      ItemCount:            LongInt;
      ItemSize:             LongInt;

      Constructor Create(s: LongInt);
      Destructor destroy;
      Procedure AddItem(Item: Pointer);

  end;

Here is some charts showing the standard naming conventions

http://delphi.about.com/od/standards/l/bldnc.htm
« Last Edit: March 20, 2012, 02:00:43 am by CaptBill »

Pascaluvr

  • Full Member
  • ***
  • Posts: 216
Re: OOP and FPC
« Reply #18 on: March 20, 2012, 01:56:00 am »
Thanks for your reply CaptBill but I'm either doing something wrong or this is not the problem.

I renamed the Destructor to Destroy

Attempting to invoke either tLinkedList.Free or tLinkedList.Destroy fails to compile, giving the error message:
'Error: Only class methods can be referred with class references'

however, invoking LL.Destroy gives exactly the same result as when it was LL.Free - that is, SIGSEGV when I try to Close the form.

( regardless, I will use Destroy in future - even tho I have seen both Destroy and Free used in the samples and tutorials on the net).

Thanks for your reply.

Oh....  I did find one problem when i was making these changes.  In the Destructor I had:
  if first = nil then exit; 
and the inherited code was not being called.

I have taken that out but still have the same problem.



Windows 7, Lazarus 1.0.8, FPC 2.6.2, SQLite 3

Pascaluvr

  • Full Member
  • ***
  • Posts: 216
Re: OOP and FPC
« Reply #19 on: March 20, 2012, 01:59:42 am »
While I was posting your last post was added.

Thank you for that reference to the naming conventions.  I'll do my best to follow that in future.
Windows 7, Lazarus 1.0.8, FPC 2.6.2, SQLite 3

CaptBill

  • Sr. Member
  • ****
  • Posts: 435
Re: OOP and FPC
« Reply #20 on: March 20, 2012, 02:08:42 am »
Thanks for your reply CaptBill but I'm either doing something wrong or this is not the problem.

I renamed the Destructor to Destroy

Attempting to invoke either tLinkedList.Free or tLinkedList.Destroy fails to compile, giving the error message:
'Error: Only class methods can be referred with class references'

however, invoking LL.Destroy gives exactly the same result as when it was LL.Free - that is, SIGSEGV when I try to Close the form.

( regardless, I will use Destroy in future - even tho I have seen both Destroy and Free used in the samples and tutorials on the net).

Thanks for your reply.

Oh....  I did find one problem when i was making these changes.  In the Destructor I had:
  if first = nil then exit; 
and the inherited code was not being called.

I have taken that out but still have the same problem.


Haha

These are the same little things that everyone encounters...I know I did (and still do).
You will soon overcome these little things.

But seriously, the naming conventions go a long way to sorting it all out. Embrace them early on for a much smother ride.

Glad you found the problem.

Pascaluvr

  • Full Member
  • ***
  • Posts: 216
Re: OOP and FPC
« Reply #21 on: March 20, 2012, 02:14:58 am »
LOL  I WISH I found the problem :)

I did find one problem but it didn't solve anything.  I still get the same result: SIGSEGV.
Windows 7, Lazarus 1.0.8, FPC 2.6.2, SQLite 3

CaptBill

  • Sr. Member
  • ****
  • Posts: 435
Re: OOP and FPC
« Reply #22 on: March 20, 2012, 02:26:23 am »
Hmm
Have you looked closely at the way you are using/calling the pointer variables (definitely not my strong point)

Everything else looks like it should work.

In fact, FPC is all about handling pointer issues behind the scenes for you. Use them only if you must. You are going outside the scope of OOP when you address pointers directly, most of the time. Let FPC work on the pointers.
I bet this is where the problem is arising from.

I will look at it again.

CaptBill

  • Sr. Member
  • ****
  • Posts: 435
Re: OOP and FPC
« Reply #23 on: March 20, 2012, 02:32:30 am »
How about just DON'T call destroy. Let the form destroy it for you. You are probably trying to destroy something that is not there anymore, hence the SIGSEV.

Try that.

99Percent

  • Full Member
  • ***
  • Posts: 160
Re: OOP and FPC
« Reply #24 on: March 20, 2012, 02:36:20 am »
What looks suspicious is your use of record and then array of char to store the values when passed with a dereference (@w[1]) You are not allocating any memory here.  Do this in the AddItem procedure or avoid using pointers.

Pascaluvr

  • Full Member
  • ***
  • Posts: 216
Re: OOP and FPC
« Reply #25 on: March 20, 2012, 02:40:20 am »
Hi CaptBill,

Thanks for your perseverance.

Taking out LL.Destroy gives same result.

With regard to the Pointers - at this stage they aren't used - they are there for when I do build a lint list.

Only 2 variables in the class are currently used :- ItemCount and ItemSize (and that is only set up on Create.

Look forward to any ideas you have ... I think I have run out.

Thanks again

In addition to you extra post.

The Record will be what is saved in the linked list.  Again at this stage I am not using it.  I guess I should delete all the unused items to avoid confusion, but as I mentioned - only 2 variables get accessed at this stage.
Windows 7, Lazarus 1.0.8, FPC 2.6.2, SQLite 3

99Percent

  • Full Member
  • ***
  • Posts: 160
Re: OOP and FPC
« Reply #26 on: March 20, 2012, 02:46:31 am »
FPC has the very useful TFPObjectList, that I think perfectly suits to what you want to do. It serves to store a list of different object. To add an object you simply pass the object (after creating it of course) to the add procedure For more info: http://www.freepascal.org/docs-html/fcl/contnrs/tfpobjectlist.html

CaptBill

  • Sr. Member
  • ****
  • Posts: 435
Re: OOP and FPC
« Reply #27 on: March 20, 2012, 02:55:51 am »
I bet 99percent is probably right. Freepascal will do this for you, just use an integer for 'item'.

Now is a good time to get to know the debugger in Lazarus and track it down. It has to do with calling an uninitialized variable somewhere when you see a SIGSEGV.

And remember that FPC shields you from needing to use pointers, except in rare cases. The compiler will use them behind the scenes, so you still get their benefits, just without having to manage them yourself. Try defining 'item' as an integer instead. Set a watch on it with the debugger and track it down.

edit: I forgot you haven't actually called the pointer now so just disregard that, other than future referrence.
« Last Edit: March 20, 2012, 03:04:19 am by CaptBill »

Pascaluvr

  • Full Member
  • ***
  • Posts: 216
Re: OOP and FPC
« Reply #28 on: March 20, 2012, 03:02:47 am »
Thanks 99%, yes that would do what I want, or at least if I extend it.

I guess I was really using this as a way to learn how to create objects/classes myself.  It seemed a simple exercise when I started and I now am getting stubborn and a simple class that only sets one variable and increments another shouldn't be beyond someone who has programmed for over 40 yearsw :(
Windows 7, Lazarus 1.0.8, FPC 2.6.2, SQLite 3

Pascaluvr

  • Full Member
  • ***
  • Posts: 216
Re: OOP and FPC
« Reply #29 on: March 20, 2012, 03:06:14 am »
hi CaptBill,

Item is not being used yet - it is the item that will be added to the LinkedList, but currently, if you look at addItem all it does is increment a counter.

I will take out everything that is not used to avoid confusion and post thge bare basics.
Windows 7, Lazarus 1.0.8, FPC 2.6.2, SQLite 3

 

TinyPortal © 2005-2018