1.无修饰符----传指针,指针被复制一份入栈。函数内修改属性值后,仅仅是修改堆中数据的值,并没有复制堆中的数据,这点与string不同,留意。
2.const 修饰符---传指针,指针被复制一份入栈。与无修饰符一致,据说加上const编译器会优化。可加可不加!!
3.var修饰符-----直接把变量现在的内存编号传过去,就是说没有任何新指针或其它【入栈】。
4.out修饰符----------与var一样,传递过来的是现在变量本身。但是会忽略变量原来的值,就是说变量的指针这个时候是个空指针,不指向任何堆中的数据。
这点与out修饰类不同,会把指针当成一个空指针。
接下来 我们实验下,不初始化IP的情况。
unit Unit4; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm4 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; /// <summary> /// 定义一个接口 /// </summary> IPerson = interface(iinterface) //接口方法 procedure makeLove(); //接口属性 function GetName : string; procedure SetName(val : string); property name: string read GetName write Setname; function Getage : Integer; procedure Setage(val : Integer); property age: Integer read Getage write Setage; end; /// <summary> /// 接口的实现类 /// 类实现的是接口的读写方法, 属性还是属于接口的; 类可以提供一个储存属性的字段 /// </summary> TPerson = class(TInterfacedObject, IPerson) private Fname: string; Fage: Integer; public procedure makeLove(); function GetName : string; procedure SetName(val : string); function Getage : Integer; procedure Setage(val : Integer); end; var Form4: TForm4; implementation {$R *.dfm} procedure abc1(ap: IPerson); begin ap.name := '李大嘴1'; end; procedure abc2(const ap: IPerson); begin ap.name := '李大嘴2'; end; procedure abc3(var ap: IPerson); begin ap.name := '李大嘴3'; end; procedure abc4(out ap: IPerson); var a: string; begin //这句会报错,因为out修饰接口的话,ap进来是入栈一个null指针,会忽略原来堆中的内存, //当成一个不指向,任何堆中地址的指针. //a := ap.name; ap := TPerson.Create;{再这里重新再堆中开辟内存空间} ap.name := 'wokao'; end; procedure TForm4.Button1Click(Sender: TObject); var ip: IPerson; begin //如果是out修饰符的话,其实这里可以不初始化,因为即使你初始化了也会被忽略. // ip := TPerson.Create; // ip.name := '小李飞刀'; // ip.age := 29; abc4(ip); Memo1.Lines.Add(ip.name); //接口不需要释放,指针出栈后,引用计数自动减少,堆中数据自动销毁. //ip.Free; end; procedure TForm4.FormCreate(Sender: TObject); begin ReportMemoryLeaksOnShutdown := True; end; { TPerson } function TPerson.Getage: Integer; begin Result := Self.Fage; end; function TPerson.GetName: string; begin Result := Self.Fname; end; procedure TPerson.makeLove; begin end; procedure TPerson.Setage(val: Integer); begin Self.Fage := val; end; procedure TPerson.SetName(val: string); begin Self.Fname := val; end; end.