(1)constrcutor到底是什么?能否认为其完全等同于class function?因为,首先它是个类方法,其次
它有返回值。(2)Create显然不是Virtual的,我在派生类中声明一个完全一样的Create函数,不需要使用override
指示字。但我的Create是不是就隐藏了TObject的Create了?无法调用基类的Create函数了。
既然不是虚方法,那么为什么我声明不同参数的Create函数,不需要使用overload指示字也能编译通过?(3)无法使一个类的Create函数变为私有,就算我声明一个Private的Create。有一种解释是这是编译
器魔术,编译器会自动修改Create的存取级别为public,无论你声明为什么。《Delphi技术手册》中的
解释是:这种情况下你调用的是TObject的Create。但是我自己测试了下好像不对,还是调用的自己的Cr
eate函数,但是我不太相信Ray Liscbner会是错的。(4)还是《Delphi 技术手册》在举例如何隐藏构造函数时,出现了如下代码
THelper = class
private
  constructor Create(参数列表...); overload;
public
  constructor Create; reintroduce; overload;
end;
很困惑,第一个Create声明为Private按照编译器魔术论就是没有意义的。第2个Create中居然使用了reintroduce,这个指示字仅仅用于隐藏基类虚方法的啊。实在是一团浆糊,求解

解决方案 »

  1.   

    第一个问题:转一下《悟透Delphi》第二章 DELPHI的原子世界值得注意的是,构造函数是类方法,而析构函数是对象方法!
    什么?构造函数是类方法,析构函数是对象方法!有没有搞错?
    你看看,当你创建对象时分明使用的是类似于下面的语句:
    aObject := TObject.Create;
    分明是调用类TObject的Create方法。而删除对象时却用的下面的语句:
    aObject.Destroy;
    即使使用Free方法释放对象,也是间接调用了对象的Destroy方法。
    原因很简单,在构造对象之前,对象还不存在,只存在类,创建对象只能用类方法。相反,删除对象一定是删除已经存在的对象,是对象被释放,而不是类被释放。
    Delphi之所以用constructor这个关键字,而不用普通的类方法表示构造函数
    一个原因是C++那样把名字跟类名一样的类方法当作构造函数的做法不够直观,
    另一个原因是如果用普通的类方法,不能保证一些必要的步骤被调用,
    用关键字就能保证无论怎么写类方法,编译器遇到关键字时都可以“强制”做一些必要的事情第二个问题:
    TObject.Create不是虚方法,
    在system.pas的就能看到,TObject.Create实际上什么都没有做,
    一些必需的工作,编译器在遇到constructor关键字已经做了
    而后续的动作又都交给了NewInstance,而NewInstance已经是一个虚方法,
    如果把Create再定义成虚方法,就显得不是那么必要,而且子类的构造过程也有可能会不一样第三和第四没研究过,但是感觉上应该也跟constructor这个关键字有关
    总的来说,Delphi里是通过constructor关键字来定义构造函数的,
    去掉了关键字的Create,其实就是一个普通的类方法建议有空去看看《Delphi的原子世界》、《Delphi的对象机制浅探》、《Inside VCL》第二章
    讲了很多Delphi对象方面的一些实现手法
      

  2.   

    还想请问下<悟透Delphi>是本什么样的书,网上好像只能找到片段章节,似乎这本书从未出版过,只有部分稿件
      

  3.   

    (1)constrcutor到底是什么?能否认为其完全等同于class   function?因为,首先它是个类方法,其次 
    它有返回值。 
    回答:虚不虚不是开发人员说了算,是编译器依据Borland规定编译器的认知规则说了算的。
    构造器从某种意义上说是属于类这个级别的。因为构造器是构造类的instance。没有类怎么可能构造instance呢。至于是不是function,答案是肯定的。如果不是function,怎么引用对象呢。
    我们在delphi中写的文本表达的程序语句,在编译后形成符合windows规范的PE格式,其中包括代码、数据等段,内部内容表示都是01序列。在执行的时候,system loader将pe的内容从disk存储load到内存,并开始执行。类在编辑期声明的时候就意味在运行期的创建过程。类是一个VMT,对象则是指向VMT的一个引用而已(CPP里面pointer和reference有明确的区别,delphi里面不是很强调这个概念)(2)Create显然不是Virtual的,我在派生类中声明一个完全一样的Create函数,不需要使用override 
    指示字。但我的Create是不是就隐藏了TObject的Create了?无法调用基类的Create函数了。 
    既然不是虚方法,那么为什么我声明不同参数的Create函数,不需要使用overload指示字也能编译通过? 
    回答:你在派生类中声明一个create肯定会影响到父类的构造函数,但是否隐藏,要看你的子类构造器的实现。如果使用inherited,则继承,不使用则隐藏。
    构造器可进行多态。其实没有必要问那么多为什么。如果你能声明多个异构参数列表的构造器而不使用重载指示符,则意味着构造器可进行多态。用不用重载标志不重要的,重要的是borland的人让编译器怎么理解你的代码,编译器就怎么理解。(3)无法使一个类的Create函数变为私有,就算我声明一个Private的Create。有一种解释是这是编译 
    器魔术,编译器会自动修改Create的存取级别为public,无论你声明为什么。《Delphi技术手册》中的 
    解释是:这种情况下你调用的是TObject的Create。但是我自己测试了下好像不对,还是调用的自己的Cr 
    eate函数,但是我不太相信Ray   Liscbner会是错的。 
    回答:可见性是对自身类之外的类而言的。私有是不希望外部类使用。如果构造器成为private的,这个构造函数基本也就失去了继承性----因为子类不能重载父类的构造器了。当然,这种无意义不是不可以存在。delphi技术手册这里我以前也看过,和你说的一样,的确是调用自己的构造器实现。编程是试验科学。我认为这里是ray笔误了,要不就是翻译错了(要知道,我们看的技术手册都是中文版的)(4)还是《Delphi   技术手册》在举例如何隐藏构造函数时,出现了如下代码 
    THelper   =   class 
    private 
        constructor   Create(参数列表...);   overload; 
    public 
        constructor   Create;   reintroduce;   overload; 
    end; 
    很困惑,第一个Create声明为Private按照编译器魔术论就是没有意义的。第2个Create中居然使用了reintroduce,这个指示字仅仅用于隐藏基类虚方法的啊。 
    回答:隐藏构造函数对于OO来说没有任何意义,纯粹是一种无聊的做法。
    reintroduce是隐藏了基类的virtual方法。这个有什么疑惑吗?父类的虚方法的存在是为了实现多态。
    俺有几年没做过什么开发了。这个都是很久以前学的。哪里不对难免。三年了,第一次这么认真的回帖子.....
      

  4.   

    (1)constrcutor到底是什么?能否认为其完全等同于class   function?因为,首先它是个类方法,其次 
    它有返回值。 
    //
    首先,constructor是一个类方法,但不等同与class function.
    constructor主要实现有两个方面 A)创建一块内存 B)初始化对象字段的值
    1.当使用如 TStringList.Create 时创建对象时 A,B 都执行
    2.但当在子类的 constructor 调用,例如 inherited Create 时, A不执行,B 执行;
    所以constructor 与普通class function 不同,有多一个额外的隐含参数区分情况 1. / 2. 
    另外 constructor 的返回值会随类的不同而不同的这一点也决定它与普通的 class function 不同.(2)Create显然不是Virtual的,我在派生类中声明一个完全一样的Create函数,不需要使用override 
    指示字。但我的Create是不是就隐藏了TObject的Create了?无法调用基类的Create函数了。 
    既然不是虚方法,那么为什么我声明不同参数的Create函数,不需要使用overload指示字也能编译通过? 
    //
    Create的一个很重要的作用就是 对内部字段进行初始化, 很明显,父类的构造函数是不能初始化子类的字段,
    所以,直接调用父类构造函数是不正确的,所以Delphi将它隐藏也是很正常的.(3)无法使一个类的Create函数变为私有,就算我声明一个Private的Create。有一种解释是这是编译 
    器魔术,编译器会自动修改Create的存取级别为public,无论你声明为什么。《Delphi技术手册》中的 
    解释是:这种情况下你调用的是TObject的Create。但是我自己测试了下好像不对,还是调用的自己的Cr 
    eate函数,但是我不太相信Ray   Liscbner会是错的。
    //
    说这句话那位人兄说的是对的; 你觉得测试不对,是你把它们都放在同一个单元里面去. (4)还是《Delphi   技术手册》在举例如何隐藏构造函数时,出现了如下代码 
    THelper   =   class 
    private 
        constructor   Create(参数列表...);   overload; 
    public 
        constructor   Create;   reintroduce;   overload; 
    end; 
    很困惑,第一个Create声明为Private按照编译器魔术论就是没有意义的。第2个Create中居然使用了reintroduce,这个指示字仅仅用于隐藏基类虚方法的啊。 
    //
    没有意义的. 在Delphi不能隐藏已经公开的函数.
    对于OO,想法跟楼上差不多,重要的不是禁止,而是约定,所以追求无聊的事情是没有意义的.