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;

解决方案 »

  1.   


    procedure TestFun(var Test: TTest1);
    beginend;改为
    procedure TestFun(Test: TTest1);
    beginend;
      

  2.   

    TO : 楼上的(楼主)类对象的变量名字本来就是一个地址。 Test1 := Test2;时,只是把Test1指向了Test2,并没有“复制”一个对象。
    还是因为“类对象的变量名字本来就是一个地址”,所以procedure TestFun(Test: TTest1);就已经是传址了,不会在过程内部生成一个对象的副本。
      

  3.   

    给楼主一段测验代码:procedure Test(E : TEdit);
    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;
      

  4.   

    楼主可以把我的Test过程改为:procedure Test(E : TEdit);
    begin
      ShowMessage(Format('%x',[integer(E)]));
      E.Text := 'Tested';
    end;然后,把Button1OnClick事件代码中Test(E2);这句后面加上一句:ShowMessage(E2.Text);看一下,是不是。
      

  5.   

    //首先多谢上面的两位,其实我真搞不懂,为什么变量没有被初始化,代码如下,还拜托看下:// ************ begin CRMFormUnit.pas ************
    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 ************
      

  6.   

    不要用TForm类测试。别忘了,TForm对象在实现时是有一个*.dfm文件的
    (个人浅见)
      

  7.   

    哦,你在FormClass.CRMCreate(Application, InitCode);时,使用的是TCRMForm类的构造方法,而TCRMForm类没有TfrmCustList的Panel1这个成员。绕来绕去绕得我好晕...
      

  8.   

    哦,你在FormClass.CRMCreate(Application, InitCode);时,使用的是TCRMForm类的构造方法,而TCRMForm类没有TfrmCustList的Panel1这个成员。
    ========================================
    我个人的看法,其实并不象你所说的那样.
    OpenForm(TfrmCustList, frmCustList, 'TestCode');
    在这个语句后加一条语句检测你就知道,
    if Assigned(frmCustList) then
      ShowMessage('OK')
    else
      ShowMessage('NO')1.frmCustList是类TfrmCustList的对象,而TfrmCustList从TCRMForm继承,TfrmCustList继承了CMCreate构造函数,而我在实例对象frmCustList中使用Panel1应该是没有问题的;2.你会发觉frmCustList还只是处于声明状态,根本还没有实例化,所以编译时没有出错,但是运行期时试图使用一个未实例化的对象就出错了!
      

  9.   

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

  10.   

    procedure OpenForm(FormClass: TCRMFormClass; var FormName; InitCode: string);
    begin
      TCRMForm(FormName) := FormClass.CRMCreate(Application, InitCode);
      TCRMForm(FormName).Show;
      // others
    end;
      

  11.   

    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;
     好像有内在泄露吧?
      

  12.   

    TestFun(Test2);改成TestFun(TTest1(Test2));
      

  13.   

    不过貌似去掉var后就不需要这样写了 -_-
      

  14.   

    (我)哦,你在FormClass.CRMCreate(Application, InitCode);时,使用的是TCRMForm类的构造方/法,而TCRMForm类没有TfrmCustList的Panel1这个成员。
    ========================================
    (楼主)我个人的看法,其实并不象你所说的那样.
    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,显示的是哪个类。
      

  15.   

    好像有内在泄露吧?
    =======================
    为了测试,没考虑那么多!其实我贴出的样例代码中有多次存在内存泄露!!!
    不过还是多谢提醒:)真诚感谢 lihuasoft(学习低调做人) 的热心讨论:)问题已经解决,晚上结贴.