Delphi与C++的语法区别
目录
∙ Delphi永远没办法在栈上创建一个对象
∙ Delphi的构造函数更象是个类方法(静态成员函数)
∙ Delphi的析构函数中可以调用纯虚方法
∙ Delphi在构造对象时自动将成员变量清零
∙ Delphi构造函数中抛出异常会自动先调用析构函数
∙ Delphi简化了COM接口的AddRef、Release和QueryInterface
一、Delphi永远没办法在栈上创建一个对象
下面是一段常见的的Delphi代码,在过程的开头声明本过程所需要的全部局部变量:
procedure Foo;
var
obj: TObject; //这句容易被C++程序员误会。
begin
...
end;
var
obj: TObject; //这句容易被C++程序员误会。
begin
...
end;
C++程序员会以为obj这个变量就是TObject对象实例本身,会以为这一句是在栈上声明并构造了TObject类的一个对象实例,他们会与下面的C++代码混淆:
void Foo() { CObject obj; //这一句的确在栈上构造了CObject类的
... //一个对象实例,并且将在离开Foo函数时自动析构它
}
... //一个对象实例,并且将在离开Foo函数时自动析构它
}
牢记一点,在Delphi里,永远不可能在栈上构造一个对象,也永远不可能对一个对象进行值传递,程序员能看到的是“指向对象实例的指针”,简单地说“一切皆指针”,上例中obj其实就是一个“TObject类型的指针”,当它在栈上被声明的时候,它的值不可知(与C++一样),也
没有任何对象被构造出来。上述代码翻译成C++,基本上就是:
void Foo() {
CObject * obj; // 声明一个CObject类型的指针
// 但没有任何对象被构造或与之关联
...
}
CObject * obj; // 声明一个CObject类型的指针
// 但没有任何对象被构造或与之关联
...
}
作为一个佐证,在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;
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,当然,析构函数肯定是虚函数。
从声明的形式上看,Create方法象是一个成员函数,但从使用上看,它更象一个类方法(C++里叫静态成员函数),因为调用它的时候,限定名不是对象,而是类名(Txxxxx.Cre
ate析构方法)。
三、Delphi的析构函数中可以调用纯虚方法
由于在Delphi的析构函数Destroy里,可以调用任何纯虚函数(在C++里这一点是不可想象的),所以可以认为这个时候,虚方法表有一定未被破坏,那么,如果基类就可以决定析构时一定要调用的函数,哪怕这个函数是个虚函数,甚至纯虚函数。
四、Delphi在构造的时候自动将成员变量清零
任何一个Delphi中的类,当它被构造后,它的所有成员变量被清零,布尔型初始为False,字符串初始为空,整型和浮点型初始化为0……而C++没有这样的保证
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论