Avatar billede simsen Mester
07. september 2011 - 20:11 Der er 5 kommentarer og
1 løsning

Kald af metoder i Class'es

Hej,

Jeg er vant til at jeg kan have lige så mange out parametre, som jeg har lyst til (C#)...men kan så læse mig til, det har man ikke samme mulighed for i Delphi....

Nu forsøger jeg, så at blive klog på procedure/function metoder i Class.

Jeg har følgende function i en klasse:
function TStringy.Replace(fromStr, toStr: String): Integer;
var
  fromSize, count, index  : Integer;
  newText : String;
  matched : Boolean;
begin
  // Get the size of the from string
  fromSize := Length(fromStr);

  // Start with 0 replacements
  count := 0;

  // We will build the target string in the newText variable
  newText := '';
  index := 1;

  // Scan the string :
  // We check for a match with the first character of the fromStr as we step
  // along the string. Only when the first character matches do we compare
  // the whole string. This is more efficient.
  while index <= Length(stText) do
  begin
    // Indicate no match for this character
    matched := false;

    // Check the first character of the fromStr
    if stText[index] = fromStr[1] then
    begin
      if AnsiMidStr(stText, index, fromSize) = fromStr then
      begin
        // Increment the replace count
        Inc(count);

        // Store the toStr in the target string
        newText := newText + toStr;

        // Move the index past the from string we just matched
        Inc(index, fromSize);

        // Indicate that we have a match
        matched := true;
      end;
    end;

    // if no character match :
    if not matched then
    begin
      // Store the current character in the target string, and
      // then skip to the next source string character
      newText := newText + stText[index];
      Inc(index);
    end;
  end;

  // Copy the newly built string back to stText - as long as we made changes
  if count > 0 then stText := newText;

  // Return the number of replacements made
  Result := count;
end;

Så vidt jeg forstår ovennævnte kode, tæller den hvor mange gange den ændrer et bogstav/sætning til et andet og ikke mindst indsætter stText til at være den nye tekst.

Fint nok.

Nu forsøger jeg så at tilgå functionen fra min kode:

procedure TForm1.Button1Click(Sender: TObject);
  var
    S : string;
    T : string;
    J: integer;
    I : integer;

begin
  S := Edit1.Text;
  T := 't';
  I := TStringy.Create(S).WordCount;
  J := TStringy.Create(S).Replace(T, 'X');
  Label1.Caption := IntToStr(J);
  Label2.Caption := TStringy.Create(S).Text;
end;

Den del med udparameter integer forstår jeg så godt......Den tæller antal gange den ændrer bogstavet/ordet og sætter det ud i J variablen.

Det store spørgsmål er, at jeg også i koden, kan se at den ændrer stText værdien til den nye værdi:

if count > 0 then stText := newText;

men men hvordan får jeg fat i den nye stText værdi i min buttonClick kode?

Et eller andet sted, har jeg på fornemmelsen, at det er fordi jeg opretter et nyt objekt hver gang jeg bruger TStringy.Create(S)....og den dermed lukker min  J := TStringy.Create(S).Replace(T, 'X'); ned igen....

Men forsøger jeg at oprette én instans, så får jeg en 'Access violation' på denne linje J := Clazz.Create(S).Replace(T, 'X');

Min kode for at tilgå én instans af Tstringy klassen:

procedure TForm1.Button1Click(Sender: TObject);
  var
    S : string;
    T : string;
    J: integer;
    I : integer;
    Clazz : TStringy;

begin
  S := Edit1.Text;
  T := 't';
  I := Clazz.Create(S).WordCount;
  J := Clazz.Create(S).Replace(T, 'X');
  Label1.Caption := IntToStr(J);
  Label2.Caption := Clazz.Create(S).Text;
end;

Så mit spørgsmål er......Hvordan får jeg ovennævnte kode til at virke, så jeg også får stText værdien med ud fra min klasse?

mvh
simsen :-)
Avatar billede arne_v Ekspert
07. september 2011 - 20:27 #1
C#:

void p(int a, ref in b)

Pascal:

procedure p(a : integer; var b : integer)

burde vaere ens.
Avatar billede arne_v Ekspert
07. september 2011 - 20:27 #2
Pointen er altsaa var keywordet.
Avatar billede simsen Mester
07. september 2011 - 22:27 #3
arne

Weeeeeeee - dejligt også at se dig herinde også.  :-))

Du er bare en snut....Men det her afleder altså et andet/tillægsspørgsmål fra mig af.....

Jeg har læst, jeg skal bruge en constructer (anbefalet - som jeg så også gør);

constructor TStringy.Create(Text: String);
begin
  stText        := Text;        // Save the passed string
  stFindPosition := 1;            // Start a search at the string start
  stFindString  := '';          // No find string provided yet
  GetWordCount;                  // Call a subroutine to get the word count
end;

Hvad er ideen med en constructer i en procedure? Jeg spørger, fordi jeg har ændret funktionen til en procedure, og kan nu se, at den ikke tager constructerens stText med i proceduren - den er blank.

Og så er det jeg ikke kan se formålet med en constructer, når jeg kalder proceduren;

TStringy.Create(S).Replace('t', 'X', T, J);

og i tilfælde af du vil have al koden:

constructor TStringy.Create(Text: String);
begin
  stText        := Text;        // Save the passed string
  stFindPosition := 1;            // Start a search at the string start
  stFindString  := '';          // No find string provided yet
  GetWordCount;                  // Call a subroutine to get the word count
end;

procedure TStringy.Replace(fromStr, toStr: String; var strNewText: String; var strCount: Integer);
var
  fromSize, count, index  : Integer;
  newText : String;
  matched : Boolean;
begin
  fromSize := Length(fromStr);

  count := 0;

  newText := '';
  index := 1;

  while index <= Length(stText) do
  begin
    matched := false;

    if stText[index] = fromStr[1] then
    begin
      if AnsiMidStr(stText, index, fromSize) = fromStr then
      begin
        Inc(count);

        newText := newText + toStr;

        Inc(index, fromSize);

        matched := true;
      end;
    end;

    if not matched then
    begin
      newText := newText + stText[index];
      Inc(index);
    end;
  end;

  if count > 0 then stText := newText;

  // Return the number of replacements made
  strCount := count;
  strNewText := stText;
  //strCount := 5;
  //strNewText := 'Tekst efter metodekald';
end;

TStringy.Create(S).Replace('t', 'X', T, J);
  Label1.Caption := IntToStr(J);
  Label2.Caption := T;

Outputtet bliver 0 i Label1 og (blank - altså ingenting) i Label2
Avatar billede simsen Mester
07. september 2011 - 22:41 #4
Kæft hvor er jeg tumpet.....

Den tager jo teksten og bruger den.....altså når jeg husker at tildele en tekst til min variabel:

S := Edit1.Text;
  TStringy.Create(S).Replace('t', 'X', T, J);

Smid et svar og du får dine points....Og endnu engang tak for hjælpen :-)
Avatar billede arne_v Ekspert
07. september 2011 - 23:09 #5
svar
Avatar billede tolderlund Nybegynder
12. september 2011 - 10:14 #6
Det her:
begin
  S := Edit1.Text;
  T := 't';
  I := TStringy.Create(S).WordCount;
  J := TStringy.Create(S).Replace(T, 'X');
  Label1.Caption := IntToStr(J);
  Label2.Caption := TStringy.Create(S).Text;
end;

er forkert.
Du laver en Create, men mangler en Free af objektet, så du får en memory leak.
Free er nødvendig da Delphi har ikke garbage collection.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester