![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ошибка компилятора ? [D6, Win2k]
Eugene Lachinov © (2002-07-10 11:14:00)Если объявить
function InputDialog(const ATitle, APrompt : string;
AInputType : TInputType;
var AText : String;
HelpCtx : Longint = 0;
SelectClick : TSelectValueEvent = nil;
KeyDown : TKeyEvent = nil) : Boolean; overload;
, то вызов строки
InputDialog("", "", itEdit, S, 0, nil, nil) не проходит при компиляции, убираешь, компиляция проходит нормально, это обходимо ?
InputDialog("", "", itEdit, S) при overload тоже компилируется без ошибок, но иногда необходимо передать последний параметр.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
type
TSelectValueEvent = procedure (Sender : TObject; var Text : String) of object;
TInputType = (itEdit, itMemo);
function InputDialog(const ATitle, APrompt : string;
AInputType : TInputType;
var AText : String;
HelpCtx : Longint = 0;
SelectClick : TSelectValueEvent = nil;
KeyDown : TKeyEvent = nil) : Boolean;
implementation
{$R *.dfm}
function InputDialog(const ATitle, APrompt : String;
AInputType : TInputType;
var AText : String;
HelpCtx : Longint = 0;
SelectClick : TSelectValueEvent = nil;
KeyDown : TKeyEvent = nil) : Boolean;
begin
Result := False
end;
procedure TForm1.Button1Click(Sender: TObject);
var
S : string;
begin
InputDialog("", "", itEdit, S, 0, nil, nil)
end;
Игорь Шевченко (2002-07-10 14:48:00) [1]В дополнение:
Присвоение nil типу Pointer вызывает обнуление 4х байт, присвоение типу TKeyEvent (или любому TMethod) вызывает обнуление 8-ми байт :-)
Eugene Lachinov (2002-07-10 14:45:00) [2]Спасибо Всем
McSimm (2002-07-10 14:42:00) [3]> все было бы так, если бы не KeyDown : TKeyEvent = nil
Все так и есть.
В твоем случае с толку сбивает что и переменным Pointer и TKeyEvent обоим можно присваивать nil
На самом деле это совсем разные присваивания.
Eugene Lachinov (2002-07-10 14:38:00) [4]>McSimm
все было бы так, если бы не KeyDown : TKeyEvent = nil
насчет Currency это из отладки _VarFromCurr
Нас сейчас перенут в Потрепаться :)
McSimm (2002-07-10 14:24:00) [5]>значит все-таки ошибка компилятора
Нет никакой ошибки.
При поиске overload версии, компилятор :
- анализирует типы параметров.
- Если нет точного соответстви производит попытку преобразования типов
- Если преобразование невозможно - выдается ошибка об отсутствии подходящей версии функции
В твоем случае константа nil определяется как тип Pointer. Преобразования Pointer - TKeyEvent невозможно, поэтому последний случай.
В приведенном мною примере константа 1.2 имеет тип Extended. Срабатывает попытка преобразования типов. Тип Double меньше Extended. Тип Variant подходит лучше. Поэтому компилятор выбирает эту функцию
Eugene Lachinov (2002-07-10 14:12:00) [6]>McSimm
значит все-таки ошибка компилятора
AAA(1.2) - 1.2 как ни странно Currency
McSimm (2002-07-10 14:03:00) [7]procedure AAA(d: double); overload;
procedure AAA(v: variant); overload;
...
Вызов AAA(1.2) - может оказаться неожиданным, так как произойдет вызов AAA(v: variant);
McSimm (2002-07-10 13:58:00) [8]>Тогда почему без overload компилируется ?
Когда функция имеет несколько overload версий компилятор производит дополнительную работу по поиску соответствующей функции. Это не всегда однозначно легко определить
Константа nil рассматривается им как тип Pointer, а такой версии нет.
Вот еще интересный случай из жизни overload:
McSimm (2002-07-10 13:55:00) [9]Компилятор не может явно преобрбразовать nil к типу TKeyEvent
Можно:
делать вызов InputDialog без последнего параметра вообще, либо с параметром явно имеющим тип TKeyEvent
или
Написать 3ю версии функции overload
Eugene Lachinov (2002-07-10 13:40:00) [10]>Толик
Тогда почему без overload компилируется ?
Толик (2002-07-10 13:37:00) [11]А-а-а. Фишка в том, что последние аргументы - указатели на ф-ю!!!
Решение:
procedure TForm1.Button1Click(Sender: TObject);
var
S : string;
Param1: TSelectValueEvent;
Param2: TKeyEvent;
begin
<>Param1 := nil;
Param2 := nil;
InputDialog("", "", itEdit, S, 0, Param1, Param2);
end;
Eugene Lachinov (2002-07-10 13:25:00) [12]Я видимо указанием текста который компилится под Delphi 6 всех запутал (удалял, добавлял overload, скопировал без него), поэтому привожу еще раз с небольшими дополнениями, надеюсь, сниму все неясности
Delphi 6 (Update 2)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
type
TSelectValueEvent = procedure (Sender : TObject; var Text : String) of object;
TInputType = (itEdit, itMemo);
function InputDialog(const ATitle, APrompt : string;
AInputType : TInputType;
var AText : String;
HelpCtx : Longint = 0;
SelectClick : TSelectValueEvent = nil;
KeyDown : TKeyEvent = nil) : Boolean; overload;
function InputDialog : Boolean; overload;
implementation
{$R *.dfm}
function InputDialog(const ATitle, APrompt : String;
AInputType : TInputType;
var AText : String;
HelpCtx : Longint = 0;
SelectClick : TSelectValueEvent = nil;
KeyDown : TKeyEvent = nil) : Boolean;
begin
Result := False
end;
function InputDialog : Boolean;
begin
Result := False
end;
procedure TForm1.Button1Click(Sender: TObject);
var
S : string;
begin
InputDialog("", "", itEdit, S, 0, nil, nil)
end;
end.
Игорь Шевченко (2002-07-10 13:15:00) [13]А посмотреть второе объявление можно ?
Если overload, то подразумевается, что имеется два объявления процедуры с одним именем, но с РАЗНЫМИ параметрами
McSimm (2002-07-10 13:15:00) [14]IMHO тут недоразумение.
overloadиспользуется для объявления несколькихфункций с одинаковым именем и разными параметрами
назначение параметрам defaultзначений не имеет к overloadотношения
Толик (2002-07-10 13:14:00) [15]function InputDialog(const ATitle, APrompt : string;
AInputType : TInputType;
var AText : String;
HelpCtx : Longint = 0;
SelectClick : TSelectValueEvent = nil;
KeyDown : TKeyEvent = nil) : Boolean; overload;
Правильно ли я понимаю, что в другой overload-функции отсутствуют некоторые параметры, объявленные здесь по умолчанию? Если это так, то при вызове InputDialog("", "", itEdit, S) компилятор совершенно справедливо не может понять, какую ф-ю ему вызывать: ту, у которой много параметров, но они по умолчанию, или ту, у которой их меньше...
Короче, решение проблемы (если я её конечно правильно понял): убрать умолчание у всех параметров обеих ф-й.
Eugene Lachinov (2002-07-10 13:12:00) [16]Если
type
TSelectValueEvent = procedure (Sender : TObject; var Text : String) of object;
TInputType = (itEdit, itMemo);
function InputDialog(const ATitle, APrompt : string;
AInputType : TInputType;
var AText : String;
HelpCtx : Longint = 0;
SelectClick : TSelectValueEvent = nil;
KeyDown : TKeyEvent = nil) : Boolean; overload;
то нет
Игорь Шевченко (2002-07-10 13:07:00) [17]У меня под рукой только D5. Сдается мне, что код целиком может прояснить ситуацию. А приведенный кусок компилируется под D6 ?
Eugene Lachinov (2002-07-10 12:57:00) [18]Код с проблемой приведен, может проблема в Delphi 6
Игорь Шевченко (2002-07-10 12:53:00) [19]Тогда код целиком, плз
Eugene Lachinov (2002-07-10 12:42:00) [20]Текст выдран из модуля для описания проблемы, в нем есть еще одно описание InputDialog