TTest1 = class end; TTest2 = class(TTest1) end;procedure TestFun(var Test: TTest1);
beginend;procedure TForm1.Button1Click(Sender: TObject);
var
Test1: TTest1;
Test2: TTest2;
begin
Test1 := TTest1.Create;
Test2 := TTest2.Create;
Test1 := Test2; //这里可以 TestFun(Test2); //这里编译出错:Types of actual and formal var parameters must be identicalend;
beginend;procedure TForm1.Button1Click(Sender: TObject);
var
Test1: TTest1;
Test2: TTest2;
begin
Test1 := TTest1.Create;
Test2 := TTest2.Create;
Test1 := Test2; //这里可以 TestFun(Test2); //这里编译出错:Types of actual and formal var parameters must be identicalend;
procedure TestFun(var Test: TTest1);
beginend;改为
procedure TestFun(Test: TTest1);
beginend;
还是因为“类对象的变量名字本来就是一个地址”,所以procedure TestFun(Test: TTest1);就已经是传址了,不会在过程内部生成一个对象的副本。
begin
ShowMessage(Format('%x',[integer(E)]));
end;procedure TForm1.Button1Click(Sender: TObject);
var
E1,E2 : TEdit;
begin
E1 := TEdit.Create(self);
E2 := TEdit.Create(self);
E1.Left := 20;
E2.Left := 200;
E1.Text := 'Edit1';
E2.Text := 'Edit2';
E1.Parent := self;
E2.Parent := self;
E1 := E2;
showmessage(Format('E1.Text=%s, E2.Text=%s',[E1.Text,E2.Text]));
E2.Text := 'Changed';
showmessage(Format('E1.Text=%s, E2.Text=%s',[E1.Text,E2.Text])); ShowMessage(Format('%x',[integer(E2)]));
Test(E2);
end;
begin
ShowMessage(Format('%x',[integer(E)]));
E.Text := 'Tested';
end;然后,把Button1OnClick事件代码中Test(E2);这句后面加上一句:ShowMessage(E2.Text);看一下,是不是。
type
TCRMFormClass = class of TCRMForm; TCRMForm = class(TForm)
protected
// other method
public
FInitCode: string;
constructor CRMCreate(AOwner: TComponent; InitCode: string);
end;constructor TCRMForm.CRMCreate(AOwner: TComponent; InitCode: string);
begin
inherited Create(AOwner);
FInitCode := InitCode;
end;//一系列从TCRMForm继承的窗体全使用这个函数打开,并在创建的时候初始化一些字段
procedure OpenForm(FormClass: TCRMFormClass; FormName: TCRMForm; InitCode: string);
begin
FormName := FormClass.CRMCreate(Application, InitCode);
FormName.Show;
// others
end;// ************ end CRMFormUnit.pas ************// ************ begin frmCustList.pas ************
type
TfrmCustList = class(TCRMForm)
Panel1: TPanel;
private
{ Private declarations }
public
{ Public declarations }
end;var
frmCustList: TfrmCustList;// ************ end frmCustList.pas ************
// ************ begin frmMain.pas ************
type
TfrmMain = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
frmMain: TfrmMain;
procedure TfrmMain.Button1Click(Sender: TObject);
begin
OpenForm(TfrmCustList, frmCustList, 'TestCode');
frmCustList.Panel1.Caption := 'OK'; //好象frmCustList没有被赋值并初始化,出错end;// ************ end frmMain.pas ************
(个人浅见)
========================================
我个人的看法,其实并不象你所说的那样.
OpenForm(TfrmCustList, frmCustList, 'TestCode');
在这个语句后加一条语句检测你就知道,
if Assigned(frmCustList) then
ShowMessage('OK')
else
ShowMessage('NO')1.frmCustList是类TfrmCustList的对象,而TfrmCustList从TCRMForm继承,TfrmCustList继承了CMCreate构造函数,而我在实例对象frmCustList中使用Panel1应该是没有问题的;2.你会发觉frmCustList还只是处于声明状态,根本还没有实例化,所以编译时没有出错,但是运行期时试图使用一个未实例化的对象就出错了!
{ 1.我肯定你所说的"类对象的变量名字本来就是一个地址"的说法. }
{ 2.我想对于函数或过程中的形参为对象时, 使用了指向对象的地址}
{ 的方式, 而对象是地址, 即是说使用了指向地址的地址,即C++中的}
{ 二次指针,不知道这样理解对不? 如果真是这样的话, 我知道应该 }
{ 如何修改了,测试代码如下: }
{ ********************************************************* }var
Form1: TForm1;
FormEdit: TEdit; // 声明全局测试变量
procedure Fun01(Value: TEdit);
//试用带var关键字的声明方式procedure Fun01(var Value: TEdit);
var
TestEdit: TEdit;
begin
TestEdit := TEdit.Create(Form1);
TestEdit.Text := 'in TestEdit'; Value := TestEdit;
if TestEdit = FormEdit then
ShowMessage('相等')
else
ShowMessage('不等');
end;procedure TForm1.Button1Click(Sender: TObject);
begin
FormEdit := TEdit.Create(Self);
FormEdit.Text := 'in FormEdit';
Fun01(FormEdit);
//1.带var的声明方式, 显示"相等"以及"in TestEdit"
//2.不带var的声明方式,显示"不等"以及"in FormEdit",FormEdit没被过程调用修改过
ShowMessage(FormEdit.Text);
end;
begin
TCRMForm(FormName) := FormClass.CRMCreate(Application, InitCode);
TCRMForm(FormName).Show;
// others
end;
var
Test1: TTest1;
Test2: TTest2;
begin
Test1 := TTest1.Create;
Test2 := TTest2.Create;
Test1 := Test2; //这里可以 TestFun(Test2); //这里编译出错:Types of actual and formal var parameters must be identicalend;
好像有内在泄露吧?
========================================
(楼主)我个人的看法,其实并不象你所说的那样.
OpenForm(TfrmCustList, frmCustList, 'TestCode');
在这个语句后加一条语句检测你就知道,
if Assigned(frmCustList) then
ShowMessage('OK')
else
ShowMessage('NO')
--------------------------------------------关于这个问题(用Assigned判断),你去看:http://rabbitfox.blog.sohu.com/38595319.html
关于在OpenForm过程里调用的倒底是哪个类的Create方法,有一个简单的做法可以验证:你把鼠标光标移到 FormClass.CRMCreate一句的CRMCreate上去,看一下HINT,显示的是哪个类。
=======================
为了测试,没考虑那么多!其实我贴出的样例代码中有多次存在内存泄露!!!
不过还是多谢提醒:)真诚感谢 lihuasoft(学习低调做人) 的热心讨论:)问题已经解决,晚上结贴.