2014-06-18 2 views
1

USING BDS2006 : C++에서 Graphics32 Resampler_ex 예제를 변환하려고하지만 일부 코드에서 어떤 일이 발생하는지 또는 해당 코드를 다시 작성하는 방법을 이해할 수 없습니다. C++. 이 샘플에서 Graphics32 Delphi 샘플을 C++로 변환하는 데 도움이 필요합니다.

사용하는 샘플러 선택할 수있는 콤보가있다 : 이 자신의 OnChange 이벤트에 Deplhi 코드 :

{ 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; 

내 문제는이 라인에 있습니다

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; 

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

어떻게이 줄을 C++로 변환 할 수 있습니까? 코멘트 제품과 ANWERS AFTER

편집 :

좋아, 내 undertanding 넘어 보인다. 내 목적을 위해,이 코드가 너무 번거롭지 않게 복제 할 수 있다면 충분할 것입니다.

itemindex를 기반으로 스위치를 사용하여 올바른 클래스를 인스턴스화 할 수 있습니까?

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; 
    [...] 
}; 

내가 내가 그들 중 하나가 "커널"을 지정할 수있는 방법을 얻을하지 않습니다 .... 내가로부터 무엇을 기억에서

+0

흠, 가상 생성자. C++에서 어렵습니다. 나는 그것이 가능하다는 것을 확신하지 못한다. 클래스 목록보다는 함수 목록을 유지한다고 생각합니다. 각 함수는 매개 변수가 없으며 호출 될 때 새로 생성 된 커널 인스턴스를 반환합니다. –

답변

1

델파이 코드는 델파이 가상 생성자에 의존한다. 이 기능은 C++에는 존재하지 않습니다.

코드를 그대로 번역하려면 가상 델파이 생성자를 호출하여 클래스를 인스턴스화하는 방법을 찾아야합니다. C++에서는 그렇게 할 수 없으므로 모든 것을 묶는 데 필요한 Delphi 코드가 필요합니다. Remy의 답변 here__classid()을 사용하여 Delphi 메타 클래스를 얻는 방법을 보여줍니다. 그런 다음 인스턴스화를 수행하려면 해당 메타 클래스를 Delphi 함수에 전달해야합니다.

솔직히 나는이 문제에 대해 다소 복잡한 회신으로 간주합니다.대신 클래스 목록을 함수 목록으로 바꾸겠다고 생각합니다. 목록에있는 함수는 커널의 새 인스턴스를 인스턴스화하는 작업을 수행합니다. 따라서 클래스를 목록에 추가하는 대신 클래스의 새 인스턴스를 만드는 함수를 추가합니다. 사실 이름과 기능 사이의 맵을 원할 수도 있습니다. 모두 사용자의 필요에 따라 다릅니다.

+0

수정 된 원래 질문이 추가 설명을 요구합니다. – Parduz

+0

항목 색인 스위치가 –

+0

으로 작동합니다. 그러나 (새로운) TNearestResampler *를 TCustomKernel *에 어떻게 할당해야합니까? dymanic_casting? 또는 무엇을? – Parduz

0

:

내가 인스턴스화해야 4 개 클래스입니다 델파이 프로그래밍, 이것은 실제로 KernelList[index]에 보관 된 클래스의 인스턴스를 생성 한 다음 TCustomKernelClass으로 다시 캐스팅합니다. AFAIK가 C++에서 이러한 메커니즘은 없다,하지만 당신은 가상 CreateInstance 메서드를 도입하여 해결할 수 있습니다 :

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

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

당신은 비록 클래스의 일부 변경을 소개해야합니다. C++로 직접 해결할 수 있을지는 의문입니다.


편집 :

좋아 의견에 대 한 응답에서, 그 목록에 보관 클래스 정의가 지금 참조하십시오. C++에서 RTTI 델파이에서와 같은 광범위한 아니기 때문에, 나는 (메모리에서 작성된 컴파일하지 않을 수 있습니다)에 대한 코드를 변경할 것 :

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

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

// (...) 

Kernel = KernelList[index](); 
+1

여기에 닭고기 및 계란 시나리오가 있습니다. 'CreateInstance'를 호출 할 인스턴스가 필요합니다. –

+0

@DavidHeffernan 내 잘못으로 수업 목록에 주목하지 못했습니다. – Spook

+0

수정 된 원본 질문에 대한 추가 설명이 필요합니다. – Parduz

관련 문제