本人初从C++转向delphi,在写程序时对对象及对象指针很迷糊,特意做了一些实验,以下是实验的感受及结论,请大家给些意见一.DELPHI没有栈对象,所有的对象都是在堆上,因此创建对象一定要记得销毁,不像C++局部对象可以栈上创建并且在函数结束时被自动析构
二.函数局部变量定义的类实际是一个地址,地址指向堆中的对象,调用create构造类时实际是create在堆中创建对象,把堆地址赋给对象,因此任何类对象在栈中只占4字节
三.指向类的指针类似于基本类型的指向指针的指针
四.New(p) p为指针,是在栈上创建一个p所指类型的变量,并且把指针赋值给p, 所以p 可以为指向基本类型或record类型的指针绝不能为指向class的指针,如果这样做了,只是会在栈上分配一段sizeof(class)大小的空间而已,是没法进行构造的根据以上经验感觉在TList等容器对象存类对象时应该存堆的地址,方法如下
l       :TList;
obj1 :TTempClass;
存对象时
I.Add(Pointer(obj1));
取对象时
obj1 := TTempClass(I[n]);

解决方案 »

  1.   

    一般的书上是不会讲到这么细这么专,delphi内容那么多写到这么细得多厚啊
    有些程序设计基础在学新语言时很少会把本书重头到尾看到完 因为语言大同小异,只会有针对性的看
    在真正工作中不会给你慢慢看书的时间
      

  2.   

    楼主理解得挺好的,对象就是一个类的实体,你说的对象指针可以理解为一个类的变量,如果这个变量给初始化了,那它就是指向一个类的实例的地址,如果你把这个变量赋值给另外一个没有实例化的对象变量只是把这个实例的地址传过去而已。因为Create方法分配内存是在堆里面的,局部变量在子过程执行完毕并没有释放掉内存,所以才一定要调用Free方法进行释放。record和class类型有共性,但不能通用,不要将两者混用就行了。
      

  3.   

    DELPHI没有栈对象 错! 不仅有 而且不少
      

  4.   

    总的来说,CPP和pascal还是有一定的区别的,
      

  5.   

    前面两点说的没错,c++具有自动对象机制,我个人分析这个原因,说到底还是c++的类一定具有构造函数,所以在局部声明的时候一定会被初始化,所以一定可以在函数返回的时候销毁,而delphi只能显示构造,如果在局部单纯的声明并不会构造对象,所以在函数返回时不能确定是否可以销毁对象,只能显示析构。
    后面说的我看不太明白,指向对象的指针就是指向对象的指针,为何还类似于基本类型的指向指针的指针?例如
    pszText : PChar;
    Btn : TButton;
    pszText是指向char的指针,而Btn是指向TButton的指针,这Btn如何类似于基本类型的指向指针的指针?在d中可以这么说,“对象名是指针”,所以也没有必要单独声明指向对象的指针,如果非要像你下面写的New(p)这样,p是个指向对象的指针,也应该是分配sizeof(Pointer)的空间而不是sizeof(class)。
      

  6.   

    我所说的对象是指class
    record 指针 基本数据类型 被我归到基本类型了栈上不可能有 class对象 可以用他做为结论吗?
      

  7.   

    关于后半部分类和指针的说明
    类对象是只存在堆里面的,
    如果我们在函数中声明一个类的局部变量,他是存在栈里面的,
    那么我们显示调用构造函数
    obj := TTestClass.Create 完成了两个内容
     一是在堆中构造出testclass对象,
    二是将这个对象的地址存到栈上的局部变量中,这点难倒不和指针有些相似吗? 此时如果局部变量中再声明一个pobj :PTestClass 
    再令 pobj :=@obj;
    此时我们可以看到pobj也在栈上,因为他是局部变量,他占用四个字节,内容是栈上obj的地址 obj也是4个字节 内容是堆上TTestClass对象的地址,这不像是指向指针的指针吗如果我们有两个函数,funcsave funcload 一个全局变量cap:TList 
    我想做的事是用funcsave创建10个对象 存入cap中,再调用funcload将caplist的内容取出来显示该如何做呢第一个问题TList中存的是Pointer 他该存什么,我的答案是应该存堆上object的地址,而不是pobj,因为pobj指向的是栈上的变量,是不可靠的
    下一个问题这个地址如何表示呢,我的答案是Pointer(obj); 因此程序写法是
    cap.add(Pointer(obj))
    存储完成了该如何调用呢
    obj2:=TTestClass(cap[n]);因此类对象的实体是存在堆中的内存块,这样看来类对象obj不像是一个指针吗,而pobj就是指向指针的指针
      

  8.   

    最后一点的New说一下,New实际上也是在堆里面分配内存.
    之所以不用New创建对象是因为
    1)New只会简单的分配内存,不会调用初始化对象实例的方法.
    2)而且Delphi的class类型也是指针,指向的是类的vmt.那么new创建class的实例则只能创建一个指针大小的内存.第一点就和C++不能用malloc分配创建对象一样.