procedure TForm1.Button1Click(Sender: TObject);
var
Inf:ITest;    //定义的一个接口对象
ta:TTa;       //一般对象
begin
  if assigned(Inf) then showmessage('Inf存在');  
  if assigned(ta) then showmessage('ta存在');    //ta并没有创建
  Inf:=TTest.create;
  Greeting(Inf);
end;问题是 ta对象并没创建,为什么它的栈指针还存在了。而接口不会?delphi编译器是怎么处理这个问题

解决方案 »

  1.   

    呵呵
    procedure TForm1.Button2Click(Sender: TObject);
    var
      II: IInterfaceList;
      f:  TForm2;
    begin
      // ShowMessage(IntToStr(SizeOf(II)));
      if Assigned(II) then
        ShowMessage('II');
      if Assigned(f) then
        ShowMessage('f ' + IntToStr(SizeOf(f)));
    end;// 看看 上面的f sizeof(f) 是4 而不是SizeOf(TForm2);
    這裡 聲明了f只是一個指向TForm2對象的指針<相當於> 雖然沒有還沒有Create... 但是f是已經有分配空間的了。。我對delphi的interface了解不多...不過C++裡面的接口是用 純虛函數來實現 接口的功能我覺得就象它得名字一樣 是一個接口 可以用來被實現 而且不能有對象,<即不能實例化> 剛看了delphi得幫助文件 也說了幾點
    where (ancestorInterface) and ['{GUID}'] are optional. In most respects, interface declarations resemble class declarations, but the following restrictions apply.The memberList can include only methods and properties. Fields are not allowed in interfaces.Since an interface has no fields, property read and write specifiers must be methods.members of an interface are public. Visibility specifiers and storage specifiers are not allowed. (But an array property can be declared as default.)Interfaces have no constructors or destructors. They cannot be instantiated, except through classes that implement their methods.Methods cannot be declared as virtual, dynamic, abstract, or override. Since interfaces do not implement their own methods, these designations have no meaning.即member不能為 data, 都是public, 沒有構造函數以及析構函數 也不能被實例化,所以 
    II: IInterfaceList;這裡得聲明並不是IInterfaceList得一個實例,也算是一個類似指針得咚咚吧。還望其它兄弟來解惑
      

  2.   

    谢谢beyondtkl(大龙驹<*爱情递归 堆栈溢出&&两湖两广两河山*>) 老师:我说错:Inf:ITest;    //定义的是一个接口类,忘了接口不能实例化,只能创建它的派动类.我想问老师的是:一个类,我只是定义,并没有进行实例化对象创建,它(指针)为什么在栈中存在.
    是不是Delphi编译器怎么做的"手脚"了.
      

  3.   

    我想问老师的是:一个类,我只是定义,并没有进行实例化对象创建,它(指针)为什么在栈中存在.
    是不是Delphi编译器怎么做的"手脚"了.// ?? 為什麼會存在?? 
    1. 那你定義一個指針 或者隨便定義一個東西吧 它都是要占有實際的內存空間的
    2. Assigned(p)的實現 就是判斷 p = nil / @p = nil 之類的。。你定義了一個變量 編譯器當然要給它開辟空間 所以Assigned(p)自然是返回True的
    所以用指針的化 用之前最好現初始化,這樣更安全...
    var
     p:Pointer
    begin
      p := nil; 
    end;
      

  4.   

    stacklifo: last in first out..
    它是線性的空間。。你可以隨便找本數據結構的書 都有說的...每個進程都有屬於自己的堆&&棧....
      

  5.   

    DELPHI中变量内存分为三中
      1 局部变量例如 var i
       其数据存放在栈(Stack),这部分变量的释放由系统来做,不用程序控制。
      2 有些需要创建的变量 例如 var st:TstringList; begin st:=TstringList.create
        其数据存存放在堆里(heap)。数据要人工控制         st.free;
      3全局变量  其数据存放在内存的全局变量区。
      

  6.   

    谢谢各位热情的为小弟慷慨解囊,谢谢,再一个谢谢各位老师,由其是 beyondtkl(大龙驹<*爱情递归 堆栈溢出&&两湖两广两河山*>) 老师,谢谢
      

  7.   

    To  lovefox_zoe(爱情狐狸)
     
           刘艺<<面向对象思想>>很经典
      

  8.   

    由于这又是最后的可用分,希望各位见谅,在这里说一声Sorry,非常感谢老师,你们的热情,谢谢
      

  9.   

    其实同楼主所想的有些不一样,
    对象并未存在,只是指针没有初始化为0。
    对于接口类型,它其实也是一个指针,编译器特别对待它,把它初始化为0了。
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Intf:IInterface; //定义的一个接口   栈地址[EBP-8]
      ta:TForm1;       //一般对象         栈地址[EBP-12]
      p1:pchar;        //指向字符         栈地址[EBP-16]
      p2:pinteger;     //指向整型         栈地址[EBP-20]
    begin
      if assigned(Intf) then showmessage('Intf初始值不为0');
      if assigned(ta) then showmessage('ta初始值不为0');    //ta并没有创建
      if assigned(p1) then showmessage('p1初始值不为0');
      if assigned(p2) then showmessage('p2初始值不为0');
     //分析的时候,应该把编译优化选项optimization去掉
    //不然除了INTF,其它变量都不会在栈中分配。end;