关于Delphi函数重载的简单问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Delphi函数重载的简单问题相关的知识,希望对你有一定的参考价值。

//=================以下重载是可以的=====================
function myF(mystr:string):string;overload;
begin
Result:=mystr;
end;
function myF(myInt:Integer):string;overload;
begin
Result:=IntToStr(myInt);
end;
//=================以下重载编译不能通过=====================
type
TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
function myF(myStr:string):string;overload;
function myF(myInt:Integer):string;overload;
private
Private declarations
public
Public declarations
end;

var
Form1: TForm1;

implementation

$R *.dfm

procedure TForm1.btn1Click(Sender: TObject);
begin
Caption:=myF('2');
end;

function TForm1.myF(myStr: string): string;overload;
begin
Result:=myStr;
end;

function TForm1.myF(myInt: Integer): string;overload;
begin
Result:=IntToStr(myInt);
end;
//==========================================
错误提示:[Error] Unit1.pas(14): Only one of a set of overloaded methods can be published
我想可能是那些地方不应该要overload
zyx7742:应该不是你说的原因哦,我把第二个函数改成返回Integer的,也不行呀?

//
// 函数在类中申明的位置错误,你没看到错误提示吗,不能用publised来修饰
//放到public, parvate下面就行,看我的代码。
type
TForm1 = class(TForm)
Button1: TButton;

private
Private declarations
function myF(myStr:string):string; overload;
function myF(myInt:Integer):string;overload;
public
Public declarations
end;

var
Form1: TForm1;

implementation

$R *.dfm

function TForm1.myF(myStr: string): string;
begin
Result:=myStr;
end;

function TForm1.myF(myInt: Integer): string;
begin
Result:=IntToStr(myInt);
end;
参考技术A function myF(myStr:string):string;overload;
function myF(myInt:Integer):string;overload;
你把这两个声明放到implementation 的上面,就可以了

Delphi/pascal:用不同的原型重载构造函数

【中文标题】Delphi/pascal:用不同的原型重载构造函数【英文标题】:Delphi/pascal: overloading a constructor with a different prototype 【发布时间】:2010-12-18 01:14:45 【问题描述】:

我正在尝试使用

创建 TForm 的子类
    特定情况下的特殊构造函数,以及 默认构造函数,将保持与当前代码的兼容性。

这是我现在的代码:

interface
  TfrmEndoscopistSearch = class(TForm)
  public
    /// original constructor kept for compatibility
    constructor Create(AOwner : TComponent); overload; override;
    /// additional constructor allows for a caller-defined base data set
    constructor Create(AOwner : TComponent; ADataSet : TDataSet; ACaption : string = ''); overload;
  end;

它似乎工作,但我总是得到编译器警告:

[警告] test.pas(44): 方法 'Create' 隐藏了基本类型 'TCustomForm' 的虚拟方法 添加“重载;”在第二个构造函数不会编译之后。 “[Error] test.pas(44): 'Create' 的声明与之前的声明不同”。 使第二个构造函数成为类函数编译时不会出现任何错误或警告,但会在运行时因访问冲突而终止(所有成员 var 均为 nil)。

【问题讨论】:

【参考方案1】:

有一个非常简单的方法可以避免这种情况。 为您的新构造函数起一个不同的名称。 与其他一些流行语言不同,Delphi 有命名构造函数;您不必称它们为 Create。您可以调用新的 CreateWithDataset 而完全不干扰虚拟 Create 构造函数。

TfrmEndoscopistSearch = class(TForm)
  /// original constructor kept for compatibility
  constructor Create(AOwner: TComponent); override;
  /// additional constructor allows for a caller-defined base data set
  constructor CreateWithDataset(AOwner: TComponent; ADataSet: TDataSet; ACaption: string = '');
end;

事实上,除非你以多态方式实例化这个类,否则你甚至不需要原来的构造函数。你可以这样声明你的新的:

TfrmEndoscopistSearch = class(TForm)
  /// additional constructor allows for a caller-defined base data set
  constructor Create(AOwner: TComponent; ADataSet: TDataSet; ACaption: string = ''); reintroduce;
end;

尝试直接在 TfrmEndoscopistSearch 上调用单参数构造函数会产生编译错误。


(以多态方式创建它通常需要使用 Application.CreateForm:

Application.CreateForm(TfrmEndoscopistSearch, frmEndoscopistSearch);

这总是调用 TComponent 中引入的单参数虚拟构造函数。除非它是您的主要形式,否则您不需要这样做。我之前写过my feelings on Application.CreateForm。)

【讨论】:

这可能是最合适的解决方案,但它不是问题的答案。练习的一部分是解决问题,而不必更改已经使用一种或另一种形式的 create() 的其他 10 多个文件中的任何一个。我将这个表单从两个不同的项目合并在一起,不想分叉。 答案是有效的,但可能有点危险。如果第 3 方用户使用他可能会调用(意外)标准构造函数 (Create) 而不是新构造函数的代码。 我不明白这怎么能被认为是“危险的”,@Migrate。在我的回答中,我指出保留原始构造函数是为了兼容。也就是说,它是为了与想要调用原始构造函数的代码兼容。如果这样做是合法的,那么就无法判断这是否是“偶然的”。 但是,如果兼容性不是问题,那么这个答案中的第二个代码块已经演示了如何防止人们在有限的情况下调用原始构造函数。那么危险在哪里?【参考方案2】:

尝试在第二个overload 之前添加reintroduce,如下所示:

  TfrmEndoscopistSearch = class(TForm)
  public
    /// original constructor kept for compatibility
    constructor Create(AOwner : TComponent); overload; override;
    /// additional constructor allows for a caller-defined base data set
    constructor Create(AOwner : TComponent; ADataSet : TDataSet; ACaption : string = ''); reintroduce; overload;
  end;

这在 Turbo Delphi 中编译。我需要public 来编译它,因为published 方法的重载受到限制。

【讨论】:

砰! “reintroduce”关键字正是我们所需要的。还需要原始构造函数,因为它将数据集设置为正确的默认值。 周围的人仍然想知道关键字背后的魔力,“重载”是因为我们在同一个类中有两个同名的函数(构造函数)。 “覆盖”是因为第一个构造函数覆盖了原来的构造函数(在父类中),而“重新引入”是关闭编译器警告(我们告诉编译器“没关系,我知道我在做什么。这不是错误.").【参考方案3】:
constructor Create(AOwner:Tcomponent;str:string);overload;
... 
constructor TfrmEndoscopistSearch.Create(AOwner: Tcomponent; str: string);
    begin
    inherited Create(AOwner);
    showmessage(str);
    end;

这应该可以解决问题

【讨论】:

以上是关于关于Delphi函数重载的简单问题的主要内容,如果未能解决你的问题,请参考以下文章

Delphi/pascal:用不同的原型重载构造函数

简单的C语言问题?

Java简单实验--关于课后提到的java重载函数的简单分析

delphi 重载问题

关于拷贝构造函数和运算符重载的问题

关于拷贝构造函数和运算符重载的问题