Link to home
Start Free TrialLog in
Avatar of Respektable
Respektable

asked on

Gurus! Why won't FindClass call a Tpersistent constructor?



Ok... I have a "Carrier" component that saves a Tpersistent to a stream.  THe problem I am having is only that my loadfromstream needs to use FindClass to construct the carried Tpersistent item from the stream.  The problem is.... that findclass(S).Create is NOT calling the constructor of my custom Tpersistent object (the item being carried)... so subcomponents and properties can't be created. If I specify the class explicitly, it works fine.  The question is, why won't FindClass(s).create call the class constructor?
(Yes, I am registering the classes)


//---- THE ITEM NOT BEING CONSTRUCTED
  TCarriedItem = Class(Tpersistent)
  Private
    fcolor:Tcolor;
    fSL :TStringlist;
   public
    constructor Create; virtual;
    destructor Destroy; override;
    procedure Assign(Source:Tpersistent);override;
   published
    property Color :TColor Read Fcolor write FColor;
    Property SL :TStringlist read FSL write fSL;
  end;


//THE LOAD PROCESS THAT WORKS FINE.. except that FindClass(S) won't call the Item's constructor.  Why not?

procedure TCarrierList.LoadFromStream(Stream : TStream);
var
  c : TCarrier;  l : Integer;  S : string;
begin
  stream.position:=0;
  while Stream.Position <> Stream.Size do
  begin
    c := TCarrier.Create(nil);

      // read class of object.
    Stream.Read(l, SizeOf(l));
    SetLength(S, l);
    Stream.Read(S[1], l);

    //look up the class and apply it
    //PROBLEM IS RIGHT HERE----------

    c.Carried := TPersistentClass(FindClass(S)).Create;

    Stream.ReadComponent(c);

    // extract the object
    Item :=c.Carried;
    c.Free;
  end;
end;



If I call the class explicitly, no problem. But I cant do that. There will be several classes that need to be constructed on the fly. I must make findclass call the item's constructor.

HELP!!!!!!!
Avatar of kretzschmar
kretzschmar
Flag of Germany image

do you get an exception?
did you tried getClass instead?
Avatar of modulo
modulo

Dear expert(s),

A request has been made to delete this Q in CS:
https://www.experts-exchange.com/questions/20404190/Please-delete-post.html

Without a response in 72 hrs, a moderator will finalize this question by:

 - Saving this Q as a PAQ and refunding the points to the questionner

When you agree or disagree, please add a comment here.

Thank you.

modulo

Community Support Moderator
Experts Exchange
would be nice to see the solution,
because of paq-ing this q
Avatar of Respektable

ASKER

Thanks kretz. I solved the problem right after I posted this... and asked for it to be deleted.
well, respektable,
in the case that you do not offer the solution,
this q should be deleted rather than paq-ed,

or modulo?
Hi Respectable,

Your question will be deleted and points refunded, but both kretzschmar and I would like to store the question with an answer in the knowledge base. Thus possibly helping others with a similar problem.
That's called "PAQ-ing" and you'll get your points back ofcourse.

When you still want a delete, just add a line, no problem wioth that.

modulo

Community Support Moderator
Experts Exchange
Respektable,

your code wasn't running OK because TPersistent constructor is static. Then if you inherit all your objects from a new class TPersistentChild, maybe your code runs nice.

Try the code below:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TPersistentChild = class(TPersistent)
  public
    constructor Create; virtual;
  end;

  TPersistentChildClass = class of TPersistentChild;

  TPersistentItem = class(TPersistentChild)
  private
    fi: Integer;
  public
    constructor Create; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  p : TPersistentChild;
begin
  p := TPersistentChildClass(FindClass('TPersistentItem')).Create;
end;

constructor TPersistentItem.Create;
begin
  inherited;
  showmessage(ClassName);
end;

constructor TPersistentChild.Create;
begin
  inherited;
end;

initialization
  RegisterClass(TPersistentItem);
end.

Douglas
Doug.. that solves one problem (which i already solved myself).. but in reference to my other post about a Streaming Tpersist... what about saving sub-objects of a Tpersistent.... just as a component would do. I know there is a generic way to do this, but i have never seen a snippet that provides an end-to-end solution. After much wondering about it, I really am not sure the overhead savings is worth it anyway.. but enough people have cautioned me about squandering resource on Tcomponents.. that I feel it worthwhile.  





ASKER CERTIFIED SOLUTION
Avatar of modulo
modulo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial