大家都知道,overload(重载)除了可以定义多个参数不相同的函数或过程以外,
还可以在子类中重载(注意,非覆盖)父类的方法,但在同一个类中是不能重载
published的方法的,即同一个类中不可以有同名方法,因为VCL要维护运行时类型信息.
如下:
type
  TSomeClass = class
  published
    function Func(P: Integer): Integer;overload;
    function Func(P: Boolean): Integer;overload;
编译器会报错.但很可惜,这样定义时,如下:
type
  TSomeClass = class
  published
    function Func(P: Integer): Integer;overload;
  public
    function Func(P: Boolean): Integer;overload;
或者这样定义时:
type
  TSomeClass = class
  public
    function Func(P: Integer): Integer;overload;
    function Func(P: Boolean): Integer;overload;编译器是不会报错,然而到了运行时该重载方法被调用时就会出现
access violation错误,
你说这是delphi的错,还是我的错?望高手指点.

解决方案 »

  1.   

    奇怪!我发现vcl中也不少重载方法呀,如TADOConnection.Execute方法!
      

  2.   

    显然是楼主您错了。
    ...
    var
      Form1: TForm1;type
      TSomeClass = class
      public
        function Func(P: Integer): Integer; overload;
        function Func(P: Boolean): Integer; overload;
      end;implementation{$R *.dfm}function TSomeClass.Func(P: Integer): Integer;
    begin
      Result := 1;
    end;function TSomeClass.Func(P: Boolean): Integer;
    begin
      Result := 2;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      with TSomeClass.Create do try
        Caption :=
          IntToStr(Func(1)) + ' ' + IntToStr(Func(False));
      finally
        Free;
      end;
    end;end.
    上面的代码没有任何问题。
    “不能发布同名的重载例程”是Object Pascal规定的。你在overload处按F1就可以得到相关的帮助信息。
      

  3.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TSomeClass = class
      public
        function Func(P: Integer): Integer; overload;
        function Func(P: Boolean): Integer; overload;
      end;  TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      MyClass: TSomeClass;implementation{$R *.dfm}{ TSomeClass }function TSomeClass.Func(P: Integer): Integer;
    begin
      Result := 1;
    end;function TSomeClass.Func(P: Boolean): Integer;
    begin
      Result := 2;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      ShowMessage(IntToStr(MyClass.Func(1)));
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      ShowMEssage(IntToStr(MyClass.Func(True)));
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      MyClass := TSomeClass.Create;
    end;end.没有创建类实例
      

  4.   

    估计您在调用方法之前没有创建对象实例。
    俺上面说的“发布”是指“published”。
      

  5.   

    怎么“alphax()”写的代码与俺的如出一辙?俺相信绝非抄袭。
      

  6.   

    真的要解释为什么不能重载published方法吗?
    因为Delphi的RTTI是根据名称来获取信息的,即公布的成员必须具有唯一的名称。
    此外,服务于属性的read或write的方法也不能重载。也就是说,不管在哪一层(private、protected、public、published),一旦作为某个属性的read或write方法,那么该方法就不能重载。
      

  7.   

    不好意思,太忙,差点忘记了本帖呢:)再次不好意思,我表达错了,我碰到问题的方法是一个form的方法,
    不是我上面说的被调用时出错,而是通过该方法显示form后,最后退出程序时出错.
    我现在的解决方法是,不再定义同名函数,只留一个,然后就好了,该方法丝毫
    未改.很奇怪吧?
      

  8.   

    published关键字是为了RTTI的方便使用才提出来的,是专门用来声明属性、事件的,这样,我们就可以在Design-Time对属性、事件进行处理;而不是用来声明函数、过程,它有它的专门作用。楼主的用法如果严格从Object Pascal of Delphi语法上来讲是错误,正确用法应当放在其他三个(private, protected, public)域中。