问几个关于Object Pascal的问题(大概可以归为语法问题)(50分)

  • 主题发起人 主题发起人 netCobra
  • 开始时间 开始时间
N

netCobra

Unregistered / Unconfirmed
GUEST, unregistred user!
1.Self能够指代什么?可以用在什么地方?
2.“@”和“^”运算符各是什么意思?
3.MDI子窗口关闭为什么一定要做Action := Free才能够关闭,否则只是最小化?
 
self :表示控件或对象本身,在 Form 的方法中就表示该 Form
@ 表示取变量的地址
^ 在类型定义中用来定义相应类型的指针类型;
放在指针变量旁表示指针所指的内容。

困为MDI子窗口默认情况下:close 时 不 free
 
self 在那个对象或类里就对应那个对象或类,在“类之类”中self只能代表“类之类”
比如:
TControlClass = class of TControl
private
_Member: string;
public:
class function GetMember: string;
procedure SomeMethod;
end;
当你调用如下语句:
self.GetMember
// 合法
self.SomeMethod
// 不合法!

对于^ :
当你写下 PInt = ^Integer
表示PInt是一个指针,
当你写下 PInt^ 时表示指针所指的内容

其余同意jsxjd说的! :-)

 
1.Self能够指代什么?可以用在什么地方?
指类的当前实例.再类的方法和事件中(事件其实也是方法,事件是方法指针).
2.“@”和“^”运算符各是什么意思?
@是取地址的操作符。
^在声明时放在类型的前面,表示该类型的指针类型。
^在应用时放在指针变量的后面,表示“去指针”,也就是该指针变量所指的内容。
3.MDI子窗口关闭为什么一定要做Action := Free才能够关闭,否则只是最小化?
人为什么闭着眼睛才能睡觉,睁着眼睛只能醒着?就是这样的。
 
同意jsjsd
 
我认为self指的是当前组件的宿主,如果一个button直接入在FORM上,那button.self指的就是
FORM,因为这是基于DELPHI的授权机制!
 
谢谢,照我的理解,在某个procedure中,self是只当前这个procedure所属的类,在一个form的定义中,由于所有的procedure都是在TForm的定义中的,因此在Form中使用self就是指的是Form(这里还有一点不明白,究竟指的是TForm类还是Form对象?),如果是我自己定义的一个类ClassDemo中的procedure,则self指的就是ClassDemo类(还是ClassDemo的实例?)。

请问我的理解正确吗?

To Delphigun:
你的例子中:
TControlClass = class of TControl
private
_Member: string;
public:
class function GetMember: string;
procedure SomeMethod;
end;
当你调用如下语句:
self.GetMember
// 合法
self.SomeMethod
// 不合法!

为什么self.GetMember是合法的而self.SomeMethod就是不合法的?
 
如果有两个同类型的对象,分别叫作a和b,那么
您也许不知道如何为这两个对象同时调用一个f()方法:

Banana=class
procedure f(i: Integer);
......
end;

var
a,b: Banana;
begin
a := Banana.Create();
b := Banana.Create();
a.f(1);
b.f(2);
end.
若只有一个名叫f()的方法,它怎样才能知道自己是为a还是
为b调用的呢?为了能用简便的、面向对象的语法来书写代
码——亦即“将消息发给对象”,编译器为我们完成了一些
幕后工作。其中的秘密就是第一个自变量传递给方法f(),而
且那个自变量是准备操作的那个对象的句柄。所以前述的两
个方法调用就变成了下面这样的形式:
Banana.f(a,1);
Banana.f(b,2);
这是内部的表达形式,我们并不能这样书写表达式,并试图让
编译器接受它。但是,通过它可理解幕后到底发生了什么事情。
假定我们在一个方法的内部,并希望获得当前对象的句柄。由
于那个句柄是由编译器“秘密”传递的,所以没有标识符可用。
然而,针对这一目的有个专用的关键字:self。self关键字(
注意只能在方法内部使用)可为已调用了其方法的那个对象生成
相应的句柄。可象对待其他任何对象句柄一样对待这个句柄。但
要注意,假若准备从自己某个类的另一个方法内部调用一个类方
法,就不必使用self。只需简单地调用那个方法即可。当前的
self句柄会自动应用于其他方法。所以我们能使用下面这样的代码:

Apricot=class
procedure pick();
procedure pit();
end;
procedure Apricot.pick()
begin
......
end;
procedure Apricot.pit()
begin
pick();
end;
在pit()内部,我们可以说self.pick(),但事实上无此必要。编
译器能帮我们自动完成。self关键字只能用于那些特殊的类——需
明确使用当前对象的句柄。例如,假若您希望将句柄返回给当前
对象,那么它经常在result中使用。
Leaf=class
i: Integer;
function increment(): Leaf;
procedure print();
end;
......
function Leaf.increment(): Leaf;
begin
Inc(i);
result := self;
end;
procedure Leaf.print();
begin
Showmessage(IntToStr(i));
end;

然后这样用
var
x: Leaf;
begin
x := Leaf.Create();
x.increment().increment().increment().print();
end;

由于increment()通过self关键字返回当前对象的句柄,所
以可以方便地对同一个对象执行多项操作。
 
呵呵,第一问是我面试Delphi程序员时必问的经典问题,很多人都答非所问。
 
To stargazer:那我就向您请教一下,这个Self到底指代什么?我现在好像更加糊涂了[:)]。谢谢
 
self指代对象本身(不是类,因为具体的一个对象是类的一个实例),
可以用在类的事件,方法,过程中,
编译后,self对应的是类的哪一个实例,就是指代的哪一个对象!
 
你首先要搞清楚对象和类的区别和联系,
然后在琢磨琢磨上面这些网友的发言,就可以理解了.
 
在贴段<<delphi技术手册>>上的话
比较经典的,
stargazer
在面试时估计说这些就可以了吧,呵呵.

Classes and Objects类和对象

可以将类想象为一种特殊的记录。与记录相似的是,一个类描述的是一种特殊的类型,
它由任意多个部分组成,每一个部分称为一个字段。与结构不同的是,
一个类可以包含函数和过程(称为方法method),以及属性property。
一个类可以继承自另一个类,因此,它继承了祖先类中所有的字段,方法,以及属性。
一个对象(Object)是一个类的动态实例。对象总是从堆中动态分配得来,
因此一个对象引用(object refrence)更象一个指针(但是不需要pascal的^操作符)。
当你将一个对象引用赋值给一个变量时,Delphi只是复制了指针,而不是复制整个对象实例。
程序中不再结束使用一个对象时,应当调用Free方法显式地释放该对象。
Delphi没有提供自动的垃圾收集机制(后面一章中的提到的接口除外)。
为简短起见,术语“对象引用”简称为“对象”,
但是对象更精确的表述应当是一块内存,Delphi在其中存放该对象的所有字段的值。
在Delphi中使用一个对象的唯一方法就是使用对象引用。
一个对象引用通常以一个变量的形式存在,但是也有函数或者属性返回值的形式。

类同样是一个独立的实体(与Java中的类似,但与C++中的不同)。在Delphi中,
类表现为内存中一张只读的表,表中存放着指向该类的虚方法的指针以及其他许多信息。
一个类引用(Class reference)就是指向该表的一个指针。
类引用最常见的用法是创建一个对象或者用来测试一个对象引用的类型,
也可以在其它许多场合使用。比如,
传递类引用给某个例程或者从一个函数中返回一个类引用。
类引用的类型称为元类(metaclass)。

这是我自己说的
而self则是编译器的一个保留字
在一个类的普通的过程和函数里
self就是上面说的对象引用
在一个类的类方法中
self就是上面说的类引用

其实呢self就是当你调用一个类的过程,函数或类方法时编译器所传递过来的一个
隐藏的指针值,仅此而已

3。为什么要
action := caFree;
看看源代码就可知
Forms.pas的4519行

procedure TCustomForm.Close;
var
CloseAction: TCloseAction;
begin
if fsModal in FFormState then
ModalResult := mrCancel
else
if CloseQuery then
begin
if FormStyle = fsMDIChild then //这句知道了吧
if biMinimize in BorderIcons then
CloseAction := caMinimize else
CloseAction := caNone
else
CloseAction := caHide;
DoClose(CloseAction);
if CloseAction <> caNone then
if Application.MainForm = Self then Application.Terminate
else if CloseAction = caHide then Hide
else if CloseAction = caMinimize then WindowState := wsMinimized
else Release;
end;
end;

 
jsxjd 说得已经很明白了
 
多人接受答案了。
 
后退
顶部