我有一个自定义组件类,我用它作为框架将注释和用户详细信息等加载到表单上。 Class是面板的子类,包含3个标签和一个备忘录。
关闭我的表单或尝试释放该对象后,我收到“无效的指针操作”错误。我知道这是试图释放一个对象两次,或访问不可用的RAM。但是,我不知道如何解决它。它让我退了很多,因为我必须在不同的主题上加载不同的评论,直到我清除当前评论的形式我才能做到。
以下是与课程相关的代码:
type
TSkeleton = class(TPanel)
private
fName : TLabel;
fStudNo : TLabel;
fTimeAndDate : TLabel;
fComment : TMemo;
public
Constructor Create (AOwner: TComponent); overload; override;
constructor Create(AOwner:TForm; sName, sStudNo, sTime, sDate, sComment: string; ComCount: integer); overload;
end;
{ TSkeleton }
constructor TSkeleton.Create(AOwner: TComponent);
begin
//
end;
constructor TSkeleton.Create(AOwner: TForm; sName, sStudNo, sTime, sDate,
sComment: string; ComCount: integer);
begin
inherited Create(AOwner);
Parent := AOwner;
Width := 800;
Height := 250;
Top := 448+((ComCount-1)*250);
Left := 16;
BevelInner := bvSpace;
BevelOuter := bvLowered;
fName := TLabel.Create(fName);
self.InsertControl(fName);
with fName do
begin
Caption := sName;
Font.Name := 'Garamond';
Font.Size := 30;
Left := 7;
Top := 4;
end;
fStudNo := TLabel.Create(fStudNo);
self.InsertControl(fStudNo);
with fStudNo do
begin
Caption := sStudNo;
Font.Name := 'Garamond';
Font.Size := 15;
Left := 15;
Top := 52;
end;
fTimeAndDate := TLabel.Create(fTimeAndDate);
self.InsertControl(fTimeAndDate);
with fTimeAndDate do
begin
Caption := sTime + ' ' + sDate;
Font.Name := 'Garamond';
Font.Size := 20;
Left := 583;
Top := 4;
end;
fComment := TMemo.Create(fComment);
self.InsertControl(fComment);
with fComment do
begin
Lines.Add(sComment);
Font.Name := 'Garamond';
Font.Size := 12;
Left := 152;
Top := 56;
Height := 161;
Width := 633;
ReadOnly := True;
ScrollBars := ssVertical;
end;
end;
如果您想查看其他代码(阅读文本文件,创建对象数组等),请说明。它与班级没有直接关系,因此我认为没有必要。
提前谢谢。
编辑:基于@Remy Lebeau的代码和@ NGLN的评论,我决定发布所有必要的内容。
根据@ Remy的代码修复课程后,我仍然收到错误。这让我相信错误是我使用该类的地方,特别是在我创建的对象数组中。
以前,我的代码是
for i := 0 to ComCount-1 do
begin
fArrObjects[i+1] := TSkeleton.Create(TargetForm);
with fArrObjects[i+1] do
begin
Parent := TargetForm;
TheName := fArrComments[i][0];
StudNo := fArrComments[i][1];
Time := fArrComments[i][2];
Date := fArrComments[i][3];
Comment := fArrComments[i][4];
ComCount := i+1;
end;
更改
fArrObjects[i+1]
到
fArrObjects[i]
解决了这个问题。
感谢@Remy纠正班级中的错误。
答案 0 :(得分:4)
您的代码存在一些问题。
Parent := AOwner;
不要从构造函数内部设置Parent
。调用者有责任在首先完全构造对象后设置Parent
。
您没有定义析构函数,而是使用nil
所有者创建子对象。 TSkeleton
应该是所有者,例如:
//fName := TLabel.Create(fName);
fName := TLabel.Create(Self);
...
您不应该直接致电InsertControl()
。请改用Parent
属性,例如:
//self.InsertControl(fName);
fName.Parent := Self;
...
为什么你有两个构造函数?您重写的构造函数不会执行任何操作,甚至不会调用基本构造函数,并且您的自定义构造函数不会在设计时调用(除非您有其他代码可编程地创建TSkeleton
实例)。我建议你摆脱自定义构造函数并公开已发布的属性以根据需要操作子控件。
最后,由于您要创建子组件,因此应通过TComponent.SetSubComponen()
标记它们。
话虽如此,尝试更像这样的事情:
type
TSkeleton = class(TPanel)
private
fName : TLabel;
fStudNo : TLabel;
fTimeAndDate : TLabel;
fComment : TMemo;
fTime: string;
fDate: string;
fComCount: Integer;
function GetTheName: string;
procedure SetTheName(const AValue: string);
function GetStudNo: string;
procedure SetStudNo(const AValue: string);
procedure SetTime(const AValue: string);
procedure SetDate(const AValue: string);
function GetComment: string;
procedure SetComment(const AValue: string);
procedure SetComCount(AValue: integer);
public
constructor Create (AOwner: TComponent); override;
published
property TheName: string read GetTheName write SetTheName;
property StudNo: string read GetStudNo write SetStudNo;
property Time: string read fTime write SetTime;
property Date: string read fDate write SetDate;
property Comment: string read GetComment write SetComment;
property ComCount: integer read fComCount write SetComCount;
end;
constructor TSkeleton.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Width := 800;
Height := 250;
Left := 16;
BevelInner := bvSpace;
BevelOuter := bvLowered;
fName := TLabel.Create(Self);
fName.SetSubComponent(True);
fName.Parent := Self;
fName.Font.Name := 'Garamond';
fName.Font.Size := 30;
fName.Left := 7;
fName.Top := 4;
fStudNo := TLabel.Create(Self);
fStudNo.SetSubComponent(True);
fStudNo.Parent := Self;
fStudNo.Font.Name := 'Garamond';
fStudNo.Font.Size := 15;
fStudNo.Left := 15;
fStudNo.Top := 52;
fTimeAndDate := TLabel.Create(Self);
fTimeAndDate.SetSubComponent(True);
fTimeAndDate.Parent := Self;
fTimeAndDate.Font.Name := 'Garamond';
fTimeAndDate.Font.Size := 20;
fTimeAndDate.Left := 583;
fTimeAndDate.Top := 4;
fComment := TMemo.Create(Self);
fComment.SetSubComponent(True);
fComment.Parent := Self;
fComment.Font.Name := 'Garamond';
fComment.Font.Size := 12;
fComment.Left := 152;
fComment.Top := 56;
fComment.Height := 161;
fComment.Width := 633;
fComment.ReadOnly := True;
fComment.ScrollBars := ssVertical;
end;
function TSkeleton.GetTheName: string;
begin
Result := fName.Caption;
end;
procedure TSkeleton.SetTheName(const AValue: string);
begin
fName.Caption := AValue;
end;
function TSkeleton.GetStudNo: string;
begin
Result := fStudNo.Caption;
end;
procedure TSkeleton.SetStudNo(const AValue: string);
begin
fStudNo.Caption := AValue;
end;
procedure TSkeleton.SetTime(const AValue: string);
begin
if fTime <> AValue then
begin
fTime := AValue;
fTimeAndDate.Caption := fTime + ' ' + fDate;
end;
end;
procedure TSkeleton.SetDate(const AValue: string);
begin
if fDate <> AValue then
begin
fDate := AValue;
fTimeAndDate.Caption := fTime + ' ' + fDate;
end;
end;
function TSkeleton.GetComment: string;
begin
Result := fComment.Text;
end;
procedure TSkeleton.SetComment(const AValue: string);
begin
fComment.Text := AValue;
end;
procedure TSkeleton.SetComCount(AValue: integer);
begin
if fComCount <> AValue then
begin
fComCount := AValue;
Top := 448+((FComCount-1)*250);
end;
end;