C++Builder:应用程序中是否需要使用Application.CreateForm()方法?

4
当您在C++Builder中创建Vcl应用程序时,它会自动为您创建表单并添加类似以下内容的行:
Application->CreateForm(__classid(Tmain), &main);

我倾向于使用new创建表单,因此请删除除主表单之外的所有行(有关讨论,请参见this article by Rob Kennedy)。
我最近发现的是,CreateForm()可以创建包含纯虚拟方法的表单。这可能会导致运行时出现“pure virtual function called”的错误。相比之下,使用new创建表单会在编译时产生“无法创建抽象类的实例”错误。
由于编译时错误比运行时错误更可取,我不禁想知道是否可以在所有表单中使用new,包括主表单?Application.CreateForm()还在幕后做了哪些事情,我能复制吗?

在项目->选项->表单下,您有一个名为“自动创建表单”的列表(以及一个主表单选择)。 您可以将除主表单之外的所有表单移动到“可用表单”列表中,在运行时手动创建它们。 - Flanker
1个回答

3
CreateForm() 是用 Delphi 实现的,而 Delphi 可以愉快地实例化抽象类的对象(为什么是任何人的猜测)。当跨越 Delphi/C++ 边界时,每种语言各自提供的某些保障可能会丢失。
在 C++ 中,您可以对所有次要窗体使用 new,但不能对主窗体使用它(没有一些麻烦的话)。 Application->CreateForm() 在第一次创建 TForm 对象时分配 Application->MainForm 属性。 MainFormApplication->Run() 所需的。如果未分配 MainForm,则 Run() 将立即退出并终止进程。
此外,在 VCL 中,MainForm 属性是只读的,因此您无法手动设置它(但在 FireMonkey 中可以)。
因此,尝试通过 new 手动创建 MainForm 不值得麻烦,因为您必须复制 CreateForm()Run() 内部所做的所有事情(建立应用程序与任务栏的关系,并运行 VCL 消息循环)。最好确保您的主窗体类从一开始就不是抽象的,然后在运行时使用 CreateForm() 实例化它。让 VCL 做它的工作。

我能从TApplication派生并在派生类中使MainForm可读写吗?或者在CreateForm中还有更多的事情发生? - Nigel Hawkins
@NigelHawkins:不,你不能将MainForm属性设置为读/写,因为FMainForm成员是私有的。但是,你可以使用一些技巧来改变该值。而且,在CreateForm()中发生的事情不仅仅是设置属性。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接