关于《高手突破》的不同见解。(反正我不同意作者的观点)(1分)

  • 主题发起人 主题发起人 wr960204
  • 开始时间 开始时间
著书的话概念当然要清晰.
大家不能接受把整形指针说成是结构指针,为什么可以容忍把方法指针说成是函数指针?
最起码的严谨性要有的,否则就不叫Object Pascal程序员了。
如果这本书是给初学者看那就不应该让初学者产生错误的基本概念,如果是给高手看的那更不应该去犯低级错误。
首先方法指针和函数指针的长度就不一样。

Type
TEvent=procedure () of Object;
TProc=procedure();

showmessage('方法指针的长度是:'+Inttostr(SizeOf(TEvent)));
showmessage('函数指针的长度是:'+Inttostr(SizeOf(TProc)));
正如wk_knife所说的,函数指针是指向函数的32位指针,占4个字节。
过程的指针结构如下
PProc = ^TProc;//过程指针
 TProc = record
  Code: Pointer;//指向过程的代码
 end;
方法指针是指向一个结构。方法的指针结构如下
PMethod = ^TMethod;//方法指针
 TMethod = record
  Code: Pointer;//指向方法的代码
Data: Pointer;//指向对象的数据
 end;
我记得Nicrosoft曾经扩展过一句名言“真正的程序员用C++,聪明的程序员用Delphi,真正聪明的程序员用C++来理解Delphi”
而这里我想他一定也是用C++来理解Delphi了。
在ANSI C++中指向类成员函数的指针确实是指向类的函数的指针,也就是一个32bit指针或者一个vtbl的索引;
Delphi则是指向对象的方法的指针,实现上是一个对象指针加上一个方法指针组成的,结构如上面说的。
但是C++Builer为了兼容Delphi增加了一个__closure关键字,和of object效果相同,但与标准c++的不同。
我不知道“一个过客”是谁,如此无礼?是Nicrosoft的绝对崇拜者还是他本人,你所要做的不过是想混淆概念
极力攻击异己。难道不允许有不同的声音存在么?如果不是来讨论学术而是来攻击人身的,请不要再来。
回到理智的立场,我是为讨论技术而来的。
 
的确可以将一个函数指针赋给一个对象事件.
事件本来就是用函数指针实现的,就象winapi的回调函数,
只有一点不同,他是对象的一个成员.
讨论:http://www.delphibbs.com/delphibbs/dispq.asp?lid=1293853
 
事件是一个对象的成员,它的类型是方法指针。
这个指针指向另一个对象(也可能与事件属于同一对象)的成员过程,
它的类型一定是procedure of object而不可能是function of object.
虽然在汇编级代码中,procedure 和 function 差别不大;但在Object pascal
里两者可是不同的,起码不是赋值相容的。
把事件叫函数指针是有点过分了.
 
to lynu
虽然可以那样绕着弯附值,但毕竟说明了方法和函数不是同一个东西
 
你丫有病还是脑子进水了? 看看以前的帖子,老子可没给那个叫什么纽克索夫特的人说过什么
好话。难道只许你说话?
我的意思很明白,方法和成员函数只是叫法不同,本质是一样的。在obj pascal里面,方法的
实现仅仅是参数传递的时候隐含增加了一个self指针参数,也就是多了一个隐含参数而已,
本质上是一样的。那本书的名字就叫高手突破,虽然我没看过,不过我想的确不适合你看,
因为你看到的只有错别字。
 
所谓方法,即对象的成员函数. 名称不同而已
 
混淆视听,成员函数和函数是一回事么???
出书的人怎么会不注意用语的准确性,给人造成误解。
如果是初学者的话...哼哼
 
"一个过客"的出言不逊。不管结论如何,不应该说脏话。
 
其实,我一直就是把Delphi的事件(Event)当作在消息里面赋值得变量,
如果说得不对大家不要攻击我阿!
 
这本书我要看了,整体还是可以的。
听听大家的看法了:)
我觉得wr960204的问题提的很好,不管结果如何,我想对于初学或有一定基础的
dfw会有很大帮助的。
dfw需要这样的讨论气氛,而不仅仅只是一个问题如何解。
 
wr960204的观点本身没有错,但有一个隐含的前提,
那就是“函数”只能特指全局函数或过程,类的函数或过程
则只能称为方法,不能称为函数。
问题是谁也没有这么规定过。
这个问题的关键,是面向对象和面向过程两种体系的混淆。
在面向过程的思想中,只有函数,而且全都是全局函数,
没有方法这一说。方法是OO术语,在OO中,只有方法,没有
函数这一说。
Delphi和C++一样,都是同时支持面向对象和面向过程两种
编程风格的语言,因此术语就比较混乱。
Delphi的Help中对方法是这么定义的:
A method is a procedure or function associated with a class.
也就是说在Delphi中,存在着两种函数:全局的函数,和从属于类
的函数。并没有规定从属于类的函数就不能称为函数,只能称为方法。
Delphi中没有method关键字,从属于类的函数(或过程)的关键字
仍然是function或procedure。我没有读过这本书,仅仅从上面的讨
论来看,很难说Nicrosoft的说法不对。
procedure和procedure of object当然是不同的类型,不能互相赋值。
Help中对这个问题说得很清楚:
Procedural types allow you to treat procedures and functions as
values that can be assigned to variables or passed to other
procedures and functions. For example, suppose you define a
function called Calc that takes two integer parameters and
returns an integer:
function Calc(X,Y: Integer): Integer;
You can assign the Calc function to the variable F:
var F: function(X,Y: Integer): Integer;
F := Calc;
If you take any procedure or function heading and remove
the identifier after the word
procedure or function, what's left is the name of a procedural
type. You can use such type names directly in variable
declarations (as in the previous example) or to declare new types:
type
TIntegerFunction = function: Integer;
TProcedure = procedure;
TStrProc = procedure(const S: string);
TMathFunc = function(X: do
uble): do
uble;
var
F: TIntegerFunction;
{ F is a parameterless function that returns an integer }
Proc: TProcedure;
{ Proc is a parameterless procedure }
SP: TStrProc;
{ SP is a procedure that takes a string parameter }
M: TMathFunc;
{ M is a function that takes a do
uble (real) parameter
and returns a do
uble }
procedure FuncProc(P: TIntegerFunction);
{ FuncProc is a procedure whose only parameter
is a parameterless integer-valued function }
The previous variables are all procedure pointers--that is,
pointers to the address of a procedure or function. If you
want to reference a method of an instance object (see Classes
and objects), you need to add the words of object to the
procedural type name. For example
type
TMethod = procedure of object;
TNotifyEvent = procedure(Sender: TObject) of object;
These types represent method pointers. A method pointer
is really a pair of pointers;
the first stores the address
of a method, and the second stores a reference to the
object the method belongs to. Given the declarations
type
TNotifyEvent = procedure(Sender: TObject) of object;
TMainForm = class(TForm)
procedure ButtonClick(Sender: TObject);
...
end;
var
MainForm: TMainForm;
OnClick: TNotifyEvent
we could make the following assignment.
OnClick := MainForm.ButtonClick;
Two procedural types are compatible if they have
the same calling convention,
the same return value (or no return value), and
the same number of parameters, with identically
typed parameters in corresponding positions. (Parameter names do
not matter.)
Procedure pointer types are always incompatible with
method pointer types. The value nil can be assigned to
any procedural type.
注意上面和method pointer对应的是procedure pointer,直译过来应该是“过程指针”,
当然事实上也包括了函数指针。但国内一般都只说函数指针,表达不同而已。
wr960204指出了二者的区别,这很好。但过于咬文嚼字,窃以为没有必要。
当然可能Nicrosoft的表达也有不妥的地方,没有把问题说透。
 
请大家看Delphi中方法类型的说明
Delphi Object and Component Reference
TMethod type
TMethod stores Code and Data fields to represent a method.
Unit
System
Delphi syntax:
type
TMethod = record
Code, Data: Pointer;
end;

C++ syntax:
struct TMethod
{
void *Code;
void *Data;
};
Description
TMethod stores the Code and Data pointers for a method.
This type can be used in a type cast of a method pointer to access the code and data parts of the method pointer.
或者到System单元去看如下代码
TMethod = record
Code, Data: Pointer;
end;
 
这个家伙还没完没了了,你丫这么有文化不如去当作家
 
才看到,好
 
to 一个过客:
脾气好像是比较火爆的哦。。。


 
后退
顶部