Pascal - 分配给函数调用
我正在查看 CodeGear C++ Builder 头文件的源代码。在 Source/vcl/forms.pas
中,我找到以下代码行:
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var
Instance: TComponent;
begin
Instance := TComponent(InstanceClass.NewInstance); // 메타클래스 이용하여, 인스턴스화
TComponent(Reference) := Instance;
try
Instance.Create(Self); // 폼 생성
except
TComponent(Reference) := nil;
raise;
end;
if (FMainForm = nil) and (Instance is TForm) then
begin
TForm(Instance).HandleNeeded; // 윈도우핸들을 생성
FMainForm := TForm(Instance);
end;
end;
从上下文来看,我认为正在发生的是,此过程创建了 InstanceClass
类型的实例并返回该实例通过参考
实例。在我的调用中,InstanceClass
不是 TForm
,因此后半部分并不重要。
我对 TComponent(Reference) := Instance;
感到困惑。 从语法上看,这里发生了什么?这是通过引用进行赋值吗?这是分配一个新的 TComponent
并为实例化器参数 Reference
分配值吗? TComponent()
是类型转换吗?
I am looking at the source code for CodeGear C++ Builder header files. In Source/vcl/forms.pas
I find the following lines of code:
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var
Instance: TComponent;
begin
Instance := TComponent(InstanceClass.NewInstance); // 메타클래스 이용하여, 인스턴스화
TComponent(Reference) := Instance;
try
Instance.Create(Self); // 폼 생성
except
TComponent(Reference) := nil;
raise;
end;
if (FMainForm = nil) and (Instance is TForm) then
begin
TForm(Instance).HandleNeeded; // 윈도우핸들을 생성
FMainForm := TForm(Instance);
end;
end;
Contextually, what I think is happening is that this procedure creates an instance of type InstanceClass
and returns that instance through Reference
. In my call, InstanceClass
is not TForm
, so the second half doesn't matter.
I am confused by TComponent(Reference) := Instance;
. Syntactically, what is happening here? Is this assignment by reference? Is this assigning a new TComponent
with the instantiator argument Reference
being assigned the value? Is TComponent()
a type casting?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
过程
的签名中,形式参数reference
并不指示数据类型,而是被声明为var
可用参数。在那里,这样的变量参数接受任何数据的实际参数类型。
编译器不会强制/限制允许的数据类型,但它必须是可寻址的(即不允许使用文字)。
dataTypeName(expression)
确实是类型转换(在 Pascal 中也是非法的,但某些方言允许)。具体来说,
dataTypeName(variableName)
是一个变量类型转换。它将被视为
variableName
属于指定的数据类型。这是必要的,因为在这种特殊情况下,
reference
没有关联的数据类型。没有关联的数据类型意味着,在如何访问相关变量方面没有商定的规则(即任何读/写访问都是不可能的)。
TComponentClass
的实例,即。 e.参数InstanceClass
的数据类型,但您应该真正阅读NewInstance
方法的文档。我只能告诉你它是
TComponent
的后代,否则类型转换为不相关的类几乎没有意义。procedure
’s signature the formal parameterreference
does not indicate a data type, but is declared as avar
iable parameter.There, such variable parameters accept actual parameters of any data type.
The compiler will not enforce/restrict permissible data types, but it must be addressable (i. e. literals are not permitted).
dataTypeName(expression)
is indeed a typecast (also illegal in Pascal, but allowed by some dialects).Specifically,
dataTypeName(variableName)
is a variable typecast.It will be treated as if
variableName
was of the named data type.This is necessary, because in this particular case
reference
has no associated data type.No associated data type means, there is no agreed rule in how to access the variable in question (i. e. any read/write access is impossible).
TComponentClass
, i. e. the data type of the parameterInstanceClass
, but there you should really read the documentation of theNewInstance
method.I can only tell you it’s a descendant of
TComponent
otherwise it hardly makes sense to typecast to an unrelated class.Reference
参数是无类型的var
参数。在C++术语中,它大致相当于void*
,即任何变量的地址都可以绑定到它。该代码将Reference
类型转换为TComponent*&
或TComponent**
的等效项,然后分配Instance< /code> 变量(
TComponent*
指针)指向调用者传递的变量。该代码大致与 C++ 中的以下代码等效(除了 C++ 中不存在元类和虚拟构造函数,因此该代码实际上在 C++ 中不可用):
The
Reference
parameter is an untypedvar
parameter. In C++ terms, it is roughly equivalent tovoid*
, ie the address of any variable can be bound to it. The code is type-casting theReference
to the equivalent ofTComponent*&
orTComponent**
and then assigning theInstance
variable (aTComponent*
pointer) to the caller's passed variable.The code is roughly equivalent to the following in C++ (except that metaclasses and virtual constructors don't exist in C++, so this code is actually not usable in C++):