"Delphi总是先构造派生的类,仅当派生类调用了继承的构造器时才去构造基类。在C++中次序相反,从祖先类开始构建,最后才是派生的类。因而,假如有类C继承于B,而B继承于A,那么Delphi先是构建C,然后是B最后是A.C++先构建A,然后B,最后C。" 想必有很多人曾经读过段话;
问题:“Delphi总是先构造派生的类,仅当派生类调用了继承的构造器时才去构造基类”
1、“构造”是指什么?(希望答的具体准确一点)编译器具体要做什么??
2、前后两个“构造”含义一样吗?具体讲,就是编译器做的工作一样吗?

解决方案 »

  1.   

    构造就是construct 实例,在内存中分配空间,初试化实例变量..两个构造一样
      

  2.   

    1. 构造函数就是construct,通常一个类的初始化工作就是通过构造函数来实现。与构造相反的是析构函数destructor,它是用来释放资源。
    2、前后两个“构造”含义不一样,前者的构造是一个概念,而后者的构造是一个动词,通过构造器来构造基类。
      

  3.   

    可能是我没把问题说清楚(很抱歉):
    constructor原理我还是知道的;例如 Obj1:=Tobj.create;
    编译器将其编译实现为: 
    用TObj对应的VMT为依据,调用TObject的Create构造函数。而在Create构造函数调用了系统的ClassCreate过程,系统的ClassCreate过程又通过存储在类VMT调用NewInstance虚方法。调用NewInstance方法的目的是要建立对象的实例空间,若没有重载该方法,它就是TObject类的NewInstance。TObject类的NewInstance方法将根据编译器在VMT表中初始化的对象实例尺寸(InstanceSize),调用GetMem过程为该对象分配内存,然后调用InitInstance方法将分配的空间初始化。InitInstance方法首先将对象空间的头4个字节初始化为指向对象类对应VMT的指针,然后将其余的空间清零。建立对象实例之后,还调用了一个虚方法AfterConstruction。最后,将对象实例数据的地址指针保存到Obj1变量中,这样,Obj1对象就诞生了。 我现在有点疑惑的地方是:
    怎样理解这句话:“Delphi总是先构造派生的类,仅当派生类调用了继承的构造器时才去构造基类”
    假如 A:=Class;···B:=Class(A)  若A有自己的构造函数,B继承A的。
    那么在bo:B; bo:=B.Create;执行过程中。编译器是调用A类的构造函数来实现的。编译器应该是先构造B类,再构造A类;构造B类当然是创建对象bo必不可少的过程,那么构造A类具体是什么含义(难道要创建一个A类的对象??)?我觉得只能说是调用A类的构造函数来创建bo。请大家帮忙讲讲;
      

  4.   

    “B:=Class(A)  若A有自己的构造函数,B继承A的”
    ***************
    这样写有点问题,这样会出错的吧?B继承A的话,B的Create是先重载A的Create,然后再做B的初始化工作的。
      

  5.   

    没问题的,我的意思是说B没有重写构造函数,默认是A的。
    “B继承A的话,B的Create是先重载A的Create,然后再做B的初始化工作的。”
    “先重载A的Create”那分配的对象空间大小是A的呢?还是B的呢?(不考虑初始化)创建出的对象是A的呢?还是B的呢?
      

  6.   

    你自己不是说得很清楚吗?>>用TObj对应的VMT为依据,调用TObject的Create构造函数。而在Create构造函数调用了系统
    >>的ClassCreate过程,系统的ClassCreate过程又通过存储在类VMT调用NewInstance虚方法。
    >>调用NewInstance方法的目的是要建立对象的实例空间,若没有重载该方法,它就是TObject
    >>类的NewInstance。TObject类的NewInstance方法将根据编译器在VMT表中初始化的对象实例
    >>尺寸(InstanceSize),调用GetMem过程为该对象分配内存,然后调用InitInstance方法将
    >>分配的空间初始化。InitInstance方法首先将对象空间的头4个字节初始化为指向对象类对
    >>应VMT的指针,然后将其余的空间清零。建立对象实例之后,还调用了一个虚方法
    >>AfterConstruction。最后,将对象实例数据的地址指针保存到Obj1变量中,这样,Obj1对
    >>象就诞生了。bo: B;
    bo := B.Create;
    因为调用的的B,所以bo的InstanceSize也是就是B类的对象的InstanceSize。创建的当然是B类的对象。你说的那几句用引号引起来的话是那里听来的阿?是原话吗?说真的,如果单从字面上去理解,真的是骇人听闻的,呵呵
      

  7.   

    1,构造类是指在内存中建立这个类的VMT等一些信息,我想应该是这个意思,在没有调用基类的create是,编译器是不会在内存中为基类分配内存的。
    为对象分配内存是在一进CREATE就进行的,如果B没有重载A的CREATE,B还是有自己CREATE(从A继承得来),而不是调用A的CREATE。如果B重载了CREATE并且inherited;这才是调用A的CREATE,这时候就必须构造A了。  TBase = class
      private
        fname:string;
      public
        constructor Create(AOwner:TComponent);
      end;  Tsub = class(TBase)
      public
        constructor Create(AOwner:TComponent);
      end;
    procedure TForm1.Button1Click(Sender: TObject);
    var fb:TBase;fsub:TSub;
    begin
      fb:=TBase.Create(self);
      showmessage(fb.fname);
      fsub:=TSub.Create(self);
      showmessage(fsub.fname);
    end;
    { TBase }constructor TBase.Create(AOwner: TComponent);
    begin
      self.fname:='Base';
    end;{ Tsub }constructor Tsub.Create(AOwner: TComponent);
    begin
      inherited; //如果没有这行,不调用父类的Create
    end;
      

  8.   

    http://expert.csdn.net/Expert/topic/1492/1492518.xml?temp=.9081385
      

  9.   

    终于弄懂那段话的含义了。哎,也不知道是他说的不确切,还是我考虑的有点“多”了。
    谢谢citytramper(阿琪),谢谢各位的参与,结帐!