当前位置:首页 > Windows程序 > 正文

Delphi中对象的创建,理解对象名与对象实体的本质区别

2021-03-27 Windows程序

  2015.08.06我总结的关于New和指针的问题(见此博客),最近在使用Delphi的面向对象的时候,发现很多类似的问题,现在也要总结一下。

  目前以下的总结是针对Delphi的,对于C++我还没有实验过。

情况一:对一个对象变量多次Create         

首先说一下对象声明的时候

var ObjectA: ClassA;

  比如有一个类ClassA,用它来声明一个变量 ObjectA: ClassA; 

  注意这个时候的ObjectA相当于一个空指针,因为此时并没有创建一个对象实体(参看博客:)

接着说一下创建一个对象的时候

ObjectA:= ClassA.Create;

   如上面的代码,此时才真正在内存中创建了一个对象实体,,ObjectA指向这个实体。

其实还可以通过ObjectA再创建一个实体

ObjectA:= ClassA.Create;

  此时又新建了一个对象实体,此时ObjectA指向这个新的对象实体,但是因为ObjectA指向了新的对象实体,而又没有对象指针指向原来的对象实体,所以就造成了原来的实体的丢失,也就是内存泄露

  以一个小例子更好的说明

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) btn1: TButton; procedure btn1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; ClassA = class public name: string; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btn1Click(Sender: TObject); var ObjectA: ClassA; begin ObjectA:= ClassA.Create; ObjectA.name:= ‘xumeng‘; ObjectA:= ClassA.Create; if ObjectA.name =‘xumeng‘ then ShowMessage(‘没有新建对象‘) else ShowMessage(‘新建了对象,并且ObjectA指向了新的对象,而原来的对象实体丢失了‘); end; end.

点击按钮,程序运行的效果图如下:

代码讲解

  这个例子中,再按钮的点击方法中先ObjectA:= ClassA.Create;,此时新建了一个ClassA对象实体,ObjectA指内存中的该实体。

  然后将ObjectA的name 变量设置为 ‘xumeng‘。

  紧接着又进行了 ObjectA:= ClassA.Create; 此时又新建了一个ClassA对象实体,ObjectA指向新的对象实体。因为通过上面的代码运行之后可以看到这时候对象的name 不是 ‘xumeng‘ 了,所以就不再是原来的对象了,所以也就说明如果这样可能造成内存泄露。大多数的对象如果出现这种情况,因为丢失了对象的指针也就没有办法通过指针对对象进行释放,所以也就造成了内存泄露;也存在这样的情况,比如一个线程对象,其Execute方法是执行一个循环然后结束,并且将其FreeOnTerminate属性设置为True,那么该线程就会在执行完Execute之后自行释放,这种情况下就不会造成内存泄露。但是正如文字所描述的,这种情况实在是要有太多的前提条件,所以为了不出现内存泄露,保证软件项目的质量,一定要尽可能避免上面所提到的情况。

情况二:多个对象变量指向一个对象实体        

  这个就可以直接来个代码来看一下

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) btn1: TButton; procedure btn1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; ClassA = class public name: string; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btn1Click(Sender: TObject); var ObjectA, ObjectB: ClassA; begin ObjectA:= ClassA.Create; ObjectB:= ObjectA; ObjectA.name:= ‘xumeng‘; ObjectB.name:= ‘xumeng changes his name‘; ShowMessage(ObjectA.name); end; end.

点击按钮,程序运行的效果如下

代码讲解

  首先是ObjectA:= ClassA.Create; 就是在内存中创建了一个ClassA对象实体,然后ObjectA指向该对象实体。

  然后将ObjectA 赋值给ObjectB,注意这里的效果是ObjectB也指向了ObjectA所指向的那个内存实体,并没有新建一个内存实体。

  所以先通过ObjectA.name:= ‘xumeng‘; 给这个内存实体的name 变量赋值之后,再通过ObjectB.name:= ‘xumeng changes his name‘; 就修改了这个对象实体的name。

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/68517.html