Delphi和C 的语法区别 (关于构造和析构)_xuebabybaby-ChinaUnix博客

网友投稿 848 2022-09-23

Delphi和C 的语法区别 (关于构造和析构)_xuebabybaby-ChinaUnix博客

Delphi和C  的语法区别 (关于构造和析构)_xuebabybaby-ChinaUnix博客

目录 Delphi永远没办法在栈上创建一个对象 Delphi的构造函数更象是个类方法(静态成员函数) Delphi的析构函数中可以调用纯虚方法 Delphi在构造对象时自动将成员变量清零 Delphi构造函数中抛出异常会自动先调用析构函数 Delphi简化了COM接口的AddRef、Release和QueryInterface 一、Delphi永远没办法在栈上创建一个对象

procedure Foo;

var

obj: TObject; //这句容易被C 程序员误会。

begin

...

end;

void Foo() {

CObject obj; //这一句的确在栈上构造了CObject类的... //一个对象实例,并且将在离开Foo函数时自动析构它}

void Foo() {

CObject * obj;

//

//

但没有任何对象被构造或与之关联

...

}

作为一个佐证,在Delphi里,sizeof(TObject), sizeof(Self), sizeof(obj) 结果都是4,即一个32位指针的大小。

二、Delphi的构造函数更象是个类方法(静态成员函数)

由于Delphi不允许在栈上构造对象,那么对象实例就只能创建在堆上,Delphi没有new关键字(倒有一个名为New的procedure),而是用一种有别于C 的语法来(在堆上)构造对象:

procedure Foo;

var

obj: TObject; //obj本质上只是一个TObject类型的指针

begin

obj := TObject.Create; //在堆上构造一个TObject对象实例并将其地址赋值给obj

obj.Free; //令obj指向的对象析构

end;

与C 一样,在堆上构造的函数不会在离开作用域的时候被自动析构,所以在离开Foo这个过程之些,要调用TObject的Free方法来析构它。Free方法会调用Destroy析构函数,只不过在调用Destroy之前会判断Self是否为空,如果为空就直接返回。Delphi里的Self,就是C 里的this。

Delphi是单根继承,所有类都从TObject派生而来,而所有类的构造函数一定名为Create,而析构函数一定名为Destroy,当然,析构函数肯定是虚函数。

三、Delphi的析构函数中可以调用纯虚方法

由于在Delphi的析构函数Destroy里,可以调用任何纯虚函数(在C 里这一点是不可想象的),所以可以认为这个时候,虚方法表有一定未被破坏,那么,如果基类就可以决定析构时一定要调用的函数,哪怕这个函数是个虚函数,甚至纯虚函数。

四、Delphi在构造的时候自动将成员变量清零

任何一个Delphi中的类,当它被构造后,它的所有成员变量被清零,布尔型初始为False,字符串初始为空,整型和浮点型初始化为0……而C 没有这样的保证

五、Delphi构造函数中抛出异常会自动先调用析构函数

Delphi里,如果构造函数中抛出了异常,则会自动先执行析构函数,然后再把异常向外抛出;而在C 里,构造函数中若有异常抛出,则析构函数是不会被调用的。

六、Delphi简化了COM接口中的AddRef、Release和QueryInterface

C 里一般用模板对COM接口进行封装,而在Delphi里,AddRef、Release以及QueryInterface都被编译器隐藏掉了,当把一个IUnknown类型的变量(本质上也是一个指针)赋值给另一个变量时,编译器在背后自动AddRef,当一个IUnknown变量离开作用域的时候(再也没有人使用它),Release被自动调用,而QueryInterface被抽象为AS运算符:

procedure Foo(const AParam: IUnknown);

var

bar: IUnknown;

other: IStream;

begin

bar := AParam; //AParam指向的实例由于赋值操作被AddRef一次

other := bar as IStream; //调用了一次QueryInterface,引用计数再次加一

end; //返回时,other和bar都离开作用域,分别被调用Release各一次

C 中用模板(比如_com_ptr)也可以使引用计数自动化,不过QueryInterface就没那么方便了

七 其它关于构造函数

-----

var test:TMyClass; 在delphi中:这里的test实际是指针(一定要记住);所以必须主动调用构造和析构函数。

-------- 一般自已创建的对象要自已去释放,但对于有owner的控件(调用Create(Owner))可以不用释放,由拥有它的组件释放。

--------

对象还没有创建时其对象指针为nil.可如下判断:

if test <> nil then

------为了节约内存,优化运行,我们总是动态创建组件。可当用完之后,如果不及时彻底的将其从内存中清理出去,那就有违我们的初衷了。可怎么“杀死”所创建的组件? 比如创建了一个Edit控件,现在想让它消失,但用Edit.Free后,调用Edit.Text却仍然存在……我们知道,光Free是不行的,这只是将Edit所指向的内存空间释放了,但是指针并没有设定为nil,当调用Edit.Text时,Delphi仍然会根据Edit提供的指针访问已经释放的内存区域,所以会产生Access Violation ....错误。所以我们需要在Free后Edit:=nil或者FreeAndNil(只在Delphi5下有效)将指针nil掉,才能保证以后的正常运行。

转自:http://blog.csdn-/seawave/article/details/1340224http://topic.csdn-/t/20040111/21/2654854.htmlhttp://topic.csdn-/t/20020118/10/485390.htmlhttp://desktop.chinaitlab.com/Delphi/28134.html

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python中7个很有用的内置函数(python中的内置函数大全)
下一篇:在centos6上部署webalizer日志分析工具
相关文章

 发表评论

暂时没有评论,来抢沙发吧~