2012-12-15 1 views
1

속성 목록이있는 기본 클래스가 있습니다. 그런 다음 하위 클래스를 만들고 다른 속성을 추가하십시오. 구성 요소를 파일에 저장해야합니다. 그러나 자식 구성 요소를 저장하는 대신 부모가 기록됩니다.WriteComponent 메서드를 사용하여 TComponent 자손을 작성하는 방법은 무엇입니까?

다음은 문제를 설명하는 exaple입니다.

MyComp1 = class(TComponent) 
    strict private 
    FS: string; 
    FI: Integer; 
    published 
    property S: string read FS write FS; 
    property I: Integer read FI write FI; 
    end; 

    MyComp2 = class(MyComp1) 
    strict private 
    FS2: string; 
    published 
    property S2: string read FS2 write FS2; 
    end; 

procedure SaveIt; 
var 
    MS: TMemoryStream; 
    C1: MyComp1; 
    C2: MyComp2; 
begin 
    MS := TMemoryStream.Create; 
    try 
    C1 := MyComp1.Create(nil); 
    C1.S := 'Hallo, World!'; 
    C1.I := 100500; 
    C2 := MyComp2(C1); 
    C2.S2 := 'Second string'; 
    MS.WriteComponent(C2); 
    MS.Position := 0; 
    MS.SaveToFile('C:\test.dat'); 
    finally 
    MS.Free; 
    end; 
end; 

상세 사항 :

나는 시간이 확대되고있는 기능을 가지고있다. 그래서 TComponent (MyComp1이라고 부름)의 기본 클래스와이 유형의 변수 (MyComp : MyComp1)를 만들었습니다. 나는 기능을 확장되면 나는 이전 버전 (MyComp2 = 클래스 (MyComp1))에서 하위 클래스 새 필요한 속성을 추가하고 내가 파일에 있지만 자식 속성으로 mycomp 구성 요소를 저장해야합니다 그런 다음이

MyComp2(MyComp).S2 := 'Second string'; 

처럼 그 값을 할당을 만들 . 나는이

MyComp := MyComp2.Create(nil) 

처럼 생성 할 수 있지만 파일로 저장하는 MyComp2로 타입 캐스팅 만 MyComp1

+2

코드는 잠재적으로 힙을 손상하고 어떤 경우에 잘못된 것입니다. 당신의 진정한 질문은 무엇입니까? – kludg

+0

그것은 부모로 선언 된 자손 구성 요소를 저장하는 방법입니다. – Yuriy

+5

'C2 : = MyComp2 (C1) '을 형변환하는 것이 단지 오류인지 알고 계십니까? 시도하고있는 것은 작동하지 않아야하며 액세스 위반 가능성이 있습니다. – kludg

답변

1

당신이 MyComp1의 객체를 인스턴스화하고 있기 때문에 그것은 작동하지 않습니다의 특성 만이있다. 실제 MyComp2 개체가 메모리에 없으므로 MyComp1 개체의 MyComp2 속성에 값을 쓰는 것은 MyComp1 개체에 속하지 않는 메모리에 액세스하는 잘못된 작업이므로 더 좋지 않은 경우 충돌하고 메모리가 손상됩니다.

이 상황을 처리하는 올바른 방법은 MyComp1이 아닌 MyComp2이라는 개체 인스턴스 만 생성하는 것입니다. MyComp1에서 MyComp2 상속 회원, 그래서 당신은 예를 들면, MyComp2 객체에 MyComp1 속성에 액세스 할 수 있습니다 :

procedure SaveIt; 
var 
    MS: TMemoryStream; 
    Comp: MyComp2; 
begin 
    MS := TMemoryStream.Create; 
    try 
    Comp := MyComp2.Create(nil); 
    try 
     Comp.S := 'Hallo, World!'; 
     Comp.I := 100500; 
     Comp.S2 := 'Second string'; 
     MS.WriteComponent(Comp); 
    finally 
     Comp.Free; 
    end; 
    MS.Position := 0; 
    MS.SaveToFile('C:\test.dat'); 
    finally 
    MS.Free; 
    end; 
end; 
+0

이 코드에 동의하지만이 작업을 수행 할 필요가 없습니다. 그 속성을 설정하는 코드와 함께 버전 1에 선언 된 기본 클래스의 변수가 있습니다. 버전 2에서는 decendant 클래스 MyComp2를 만들고 부모 (MyComp : MyComp2.Create (nil)) 변수에 해당 인스턴스를 assining합니다. 상속 논리를 사용했기 때문에 각 자손 클래스와 각 새 버전에서 상위 속성의 설정을 다시 작성하고 싶지 않습니다. 난 decendant 클래스의 속성을 설정하기 만하면됩니다. MyComp2의 인스턴스를 만들 때부터 타입 캐스팅이 올바르다 고 생각했습니다. – Yuriy

+0

@Yuriy : 그러면 실제 코드를 우리에게 알려주지 않을 것입니다. MyComp2의 인스턴스를 만드는 질문에 몇 가지 진술을 보여 주지만 WriteComponent를 수행하는 코드의 다른 변수를 사용합니다. 불가능한 일이 아니라 실제 코드를 보여주지 않으면 도움이 될 것입니다. –