1

USING BDS2006 : Graphics32 Resampler_ex の例を C++ に変換しようとしていますが、一部のコードで何が起こっているのか、またはそのコードを C++ で書き直す方法さえ理解できません。

そのサンプルには、使用するリサンプラーを選択するためのコンボボックスがあります。これは、彼の OnChange イベントの Deplhi コードです。

procedure TfmResamplersExample.KernelClassNamesListClick(Sender: TObject);
var
  Index: Integer;
begin
  Index := KernelClassNamesList.ItemIndex;
  if Src.Resampler is TKernelResampler then
    with TKernelResampler(Src.Resampler) do
    begin
      Kernel := TCustomKernelClass(KernelList[Index]).Create;
      LbParameter.Visible := (Kernel is TAlbrechtKernel) or
{$IFDEF Ex}
        (Kernel is TGaussianKernel) or
        (Kernel is TKaiserBesselKernel) or
        (Kernel is TNutallKernel) or
        (Kernel is TBurgessKernel) or
        (Kernel is TBlackmanHarrisKernel) or
        (Kernel is TLawreyKernel) or
{$ENDIF}
        (Kernel is TSinshKernel);
      gbParameter.Visible := LbParameter.Visible;
      SetKernelParameter(Kernel);
      CurveImage.Repaint;
    end;
end;

どこ:

{ TClassList }
{ This is a class that maintains a list of classes. }
TClassList = class(TList)
protected
  function GetItems(Index: Integer): TClass;
  procedure SetItems(Index: Integer; AClass: TClass);
public
  function Add(AClass: TClass): Integer;
  function Extract(Item: TClass): TClass;
  function Remove(AClass: TClass): Integer;
  function IndexOf(AClass: TClass): Integer;
  function First: TClass;
  function Last: TClass;
  function Find(AClassName: string): TClass;
  procedure GetClassNames(Strings: TStrings);
  procedure Insert(Index: Integer; AClass: TClass);
  property Items[Index: Integer]: TClass read GetItems write SetItems; default;
end;
ResamplerList: TClassList;

私の問題はこの行にあります

      Kernel := TCustomKernelClass(KernelList[Index]).Create;

この行を C++ で変換するにはどうすればよいですか?

コメントと回答の後に編集:

わかりました、私の理解を超えているようです。私の目的では、このコードが行うことをあまり手間をかけずに再現できれば十分です。

itemindex に基づくスイッチを使用するだけで、適切なクラスをインスタンス化することは可能でしょうか?

これらは、インスタンス化する必要がある 4 つのクラスです。

class DELPHICLASS TNearestResampler;
class PASCALIMPLEMENTATION TNearestResampler : public Gr32::TCustomResampler 
{
    typedef Gr32::TCustomResampler inherited;
    [...]
}

class DELPHICLASS TLinearResampler;
class PASCALIMPLEMENTATION TLinearResampler : public Gr32::TCustomResampler 
{
    typedef Gr32::TCustomResampler inherited;
    [...]
};


class DELPHICLASS TDraftResampler;
class PASCALIMPLEMENTATION TDraftResampler : public TLinearResampler 
{
    typedef TLinearResampler inherited;
    [...]   
};


class DELPHICLASS TKernelResampler;
class PASCALIMPLEMENTATION TKernelResampler : public Gr32::TCustomResampler 
{
    typedef Gr32::TCustomResampler inherited;
    [...]
};

それらの1つを「カーネル」に割り当てる方法がわかりません....

4

2 に答える 2

0

Delphi プログラミングで覚えていることによると、これは実際には、現在保持されている同じタイプのクラスをインスタンス化し、KernelList[index]それを にキャストし直しTCustomKernelClassます。私の知る限り、C++ にはそのようなメカニズムはありませんが、仮想 CreateInstance メソッドを導入することで解決できます。

class TCustomKernelClass
{
public:
    virtual TCustomKernelClass * CreateInstance() = 0;
}

class TDerivedKernelClass
{
public:
    TCustomKernelClass * CreateInstance()
    {
        return new TDerivedKernelClass();
    }
}

ただし、クラスにいくつかの変更を導入する必要があります。C++で直接解決できるとは思えません。


編集:コメントに応じて

わかりました。そのリストにはクラス定義が保持されています。C++ の RTTI は Delphi ほど広範ではないため、コードを次のように変更します (メモリから書き込まれるため、コンパイルできない可能性があります)。

std::vector<std::function<TBaseKernelClass(void)>> KernelList;

KernelList.push_back([]() { return new TDerivedKernelClass(); });

// (...)

Kernel = KernelList[index]();
于 2014-06-18T10:54:17.587 に答える