访问类的私有变量出现问题?(100分)

  • 主题发起人 主题发起人 lizheng
  • 开始时间 开始时间
L

lizheng

Unregistered / Unconfirmed
GUEST, unregistred user!
TFindFile =Class
Private
FileOptions:TFileOptions;
FFileNO,FCDNO:Integer;
SaveTime,FCDName:String;
Function GetPath(Path:String):String;
Procedure FindFile;
Procedure WriteTable;
Public
Constructor Create(FindPath,CDName:String);
End;

constructor TFindFile.Create(FindPath,CDName: String);
var
DateTime:TSystemTime;
begin
Inherited Create;
GetSystemTime(DateTime)

SaveTime:=IntToStr(DateTime.wYear)+'-'+IntToStr(DateTime.wMonth)+'-'+IntToStr(DateTime.wDay);
~~~~~有错
...
...
...

Project Project1.exe raised exception class EAccessViolation
with message 'Access violation at address 00403E44 in module
'PROJECT1.EXE'.Read of address FFFFFFFF'.Process stopped.Use
Step or Run to continue.

而且我试过,只要是访问TFindFile类的私有变量都有此问题。
 
我是指在TFindFile类自己的过程或函数中访问其私有变量。
 
试一试:

constructor TFindFile.Create(FindPath,CDName: String);
var
Y,D,M:Word;begin
Inherited Create;
DecodeDate(Date, Y, D, M);
SaveTime:=IntToStr(Y)+'-'+IntToStr(D)+'-'+IntToStr(M);
或 SaveTime:=DateToStr(Date);

 
1. 定义TFindFile = class(TObject)比较好
2. FileOptions没有被初始化. 在create中添加
FileOptions=TFileOptions.create;
3. DataTime没有被初始化. 在GetSystemTime前添加
DataTime:=TSystemData.create;

ps: 我试了一下, 运行没问题呀. 我用的是Delphi 4, 没改你的程序.
也可能是你机器的内存不够了?
 
好象没问题呀,我用你的程序没出一点问题
 
GetSystemTime(DateTime)应该是可用的,
错误是出现在访问SaveTime的时候.
而且访问其他私有变量也会出现上述错误。
 
你把私有变量放到Public还会出现此问题吗?
 
我回去看看,如果还有错,我就把代码贴详细点,
到时还得请各位打下帮忙。
 
你的访问方法肯定没错,一个类当然可以访问自己的私有变量,否则这个私有变量
是给谁访问的?

我估计你的错误就是Iknow说的,使用前没有create.
 
我也试了一下,毫无问题.
 
不会有问题吧!
 
我也试过了,没错。
 
看看你的编译选项,是否有问题。
 
不要太着急可能代码输错了:-)
 
Type
TFileOptions=(......)
End;

所以FileOptions=TFileOptions.create是不必的
而且访问其他的私有变量也会出现上述问题,为什么?

// GetSystemTime(DateTime)

// SaveTime:=IntToStr(DateTime.wYear)+'-'+IntToStr(DateTime.wMonth)+'-'+IntToStr(DateTime.wDay);
我把上述两句注释掉,但访问到下一个私有变量还是会出现上述问题。

还有
DecodeDate(Date, Y, D, M);
SaveTime:=IntToStr(Y)+'-'+IntToStr(D)+'-'+IntToStr(M);
或 SaveTime:=DateToStr(Date);
和我程序中的方法有什么不同?
 
你的Create是怎么声明的?
public

constructor Create;
是吗?
另外你的基类最好用TObject;
 
Txxxx = class和 Txxx = class(Tobject)一样.
Delphi的编译器认为两者一样.

procedure TForm1.Button4Click(Sender: TObject);
var
Fll : TFindFile;
begin
// Fll.Create('f','f')
///你可能是这样写的
Fll := TFileFind.Create('g','g')
//改成这样.
try
finally
Fll.Free;
end;
end;


 
unit OperateUnit;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
InitialUnit, ComCtrls;

type
TFormType = (Initial,Query,AddNewUser,RemoveOldUser,SetPassword);

TOperateType = (lzSort,lzSearch,lzFindAndSave,lzDelete);

TFileOptions = Record
flName,flAttribution,flPath:String;
flSize,flFileNO:Integer;
End;

TOperateForm = class(TForm)
InitialFrame: TInitialFrame;
procedure InitialFrameOKClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
FormType: TFormType;
end;

TFindFile =class(TObject)
Private
FFileNO,FCDNO:Integer;
FSaveTime,FCDName:String;
FileOptions:TFileOptions;
Procedure FindFile;
Procedure WriteTable;
Public
Constructor Create(FindPath,CDName:String);
End;

TOperate = class(TObject)
Private
FindFile:TFindFile;
Public
Constructor Create(OperateType:TOperateType;FileName,FindPath:String);
End;

var
OperateForm: TOperateForm;

implementation

uses DataModule;


{$R *.DFM}

{FindFile}
{Create}
constructor TFindFile.Create(FindPath,CDName: String);
var
DateTime:TSystemTime;
begin
Inherited Create;
GetSystemTime(DateTime);
FSaveTime:=IntToStr(DateTime.wYear)+'-'+IntToStr(DateTime.wMonth)+'-'+IntToStr(DateTime.wDay);
//运行到上面一句就出错,不知为什么?
if FileDataModule.CDNOTable.RecordCount=0 then
begin
FileDataModule.CDTable.Last;
FCDNO:=FileDataModule.CDTable.FieldByName('光盘编号').AsInteger+1;
end
else
begin
FileDataModule.CDNOTable.First;
FCDNO:=FileDataModule.CDNOTable.FieldByName('光盘编号').AsInteger;
FileDataModule.CDNOTable.Delete;
end;
FCDName:=CDName;
With FileDataModule.CDTable Do
Begin
Append;
FieldByName('光盘编号').AsInteger:=FCDNO;
FieldByName('光盘名称').AsString:=FCDName;
FieldByName('光盘简介').AsString:=OperateForm.InitialFrame.IntorductionMemo.Text;
FieldByName('保存时间').AsDateTime:=StrToDateTime(FSaveTime);
End;
FileDataModule.FileTable.Last;
FFileNO:=FileDataModule.FileTable.FieldByName('文件编号').Asinteger+1;
FileOptions.flPath:=FindPath;
ChDir(FileOptions.flPath);
FindFile;
end;

procedure TFindFile.FindFile;
var
SearchRec: TSearchRec;
err:integer;
begin
try
err:=FindFirst('*.*',faAnyFile, SearchRec);
while err = 0 do
begin
Application.ProcessMessages;
if SearchRec.Name[1]<>'.' then
begin
if SearchRec.Attr = fadirectory then
begin
FileOptions.flPath:=LowerCase(ExtractFileName(SearchRec.Name));
FileOptions.flName:=LowerCase(SearchRec.Name);
FileOptions.flFileNO:=FFileNO;
FileOptions.flSize:=0;//SearchRec.Size;
FileOptions.flAttribution:='文件夹';
WriteTable;
FFileNO:=FFileNO+1;
try
ChDir(SearchRec.Name);
FindFile;
ChDir('..')
except
exit;
end;
End
else
begin
FileOptions.flPath:=LowerCase(ExpandFileName(SearchRec.Name));
FileOptions.flName:=LowerCase(SearchRec.Name);
FileOptions.flFileNO:=FFileNO;
FileOptions.flSize:=SearchRec.Size;
FileOptions.flAttribution:=LowerCase(ExtractFileExt(SearchRec.Name));
WriteTable;
FFileNO:=FFileNO+1;
end;
end;
err:= FindNext(SearchRec);
end;
finally
FindClose(SearchRec);
end;
end;
{
//GetPath
function TFindFile.GetPath(Path: String): String;
Var
Size,j:Integer;
NewPath:String;
begin
for Size:=Length(Path) DownTo 1 do
Begin
if Path[Size]='/' then
Begin
Setlength(NewPath,Size);
for j:=1 to Size do NewPath[j]:=Path[j];
Result:=NewPath;
Exit;
End;
End;
end;
}

{WriteTable}
procedure TFindFile.WriteTable;
begin
FileDataModule.FileTable.Append;
FileDataModule.FileTable.FieldByName('文件编号').AsInteger:=FileOptions.flFileNO;
FileDataModule.FileTable.FieldByName('文件名称').AsString:=FileOptions.flName;
FileDataModule.FileTable.FieldByName('光盘编号').AsInteger:=FCDNO;
// FileDataModule.FileTable.FieldByName('存入时间').AsDateTime:=StrToDateTime(FSaveTime);
FileDataModule.FileTable.FieldByName('文件类型').AsString:=FileOptions.flAttribution;
FileDataModule.FileTable.FieldByName('文件大小').AsInteger:=FileOptions.flSize;
// FileDataModule.FileTable.FieldByName('光盘名称').AsString:=lowercase(Form3.Edit1.Text);
FileDataModule.FileTable.FieldByName('所属文件夹').AsString:=FileOptions.flPath;
FileDataModule.FileTable.Post;
end;

{ TOperate }
{Create}
constructor TOperate.Create(OperateType: TOperateType
FileName,
FindPath: String);
begin
Inherited Create;
Case OperateType Of
lzSort:Begin
End;
lzSearch:Begin
End;
lzFindAndSave: FindFile.Create(FindPath,FileName);
lzDelete:Begin
End;
End;
end;

end.


我将原码贴上来了,还请各位打下多多帮忙。
(再加100分)
 
To Hexi:
把私有变量放到Public还会出现此问题
constructor TFindFile.Create(FindPath,CDName: String);
var
Y,D,M:Word;begin
Inherited Create;
DecodeDate(Date, Y, D, M);
SaveTime:=IntToStr(Y)+'-'+IntToStr(D)+'-'+IntToStr(M);
或 SaveTime:=DateToStr(Date);

//Date应该是TDateTime类型的,是在System中声明的,但我如果把它加到uses
中区会出现如下错误,我实在想不通。
[Error] OperateUnit.pas(7): Identifier redeclared: 'System'




To Iknow:
(加上DataTime:=TSystemData.create会出错;
[Error] OperateUnit.pas(66): Object or class type required
_SYSTEMTIME = record
wYear: Word;
wMonth: Word;
wDayOfWeek: Word;
wDay: Word;
wHour: Word;
wMinute: Word;
wSecond: Word;
wMilliseconds: Word;
end;
{$EXTERNALSYM _SYSTEMTIME}
TSystemTime = _SYSTEMTIME;
}


 
你是如何使用TFindFile类的?

t := TFindFile.Create('df','d');
不要 t.Create;
 
后退
顶部