Почему процедура-метод вызывается с "чужим" умолчательным значением?
package X is
type A is tagged null record;
procedure foo ( Self : in A; num : Integer := 0);
type B is new A with null record;
procedure foo (Self: in B; num : Integer := 10);
procedure test (some : A'class);
end X;
with Ada.Text_IO; use Ada.Text_IO;
package body X is
procedure foo ( Self : in A; num : Integer := 0) is
begin
Put_Line("foo A");
Put_Line(Integer'Image(num));
end foo;
procedure foo (Self: in B; num : Integer := 10) is
begin
Put_Line("foo B");
Put_Line(Integer'Image(num));
end foo;
procedure test (some : A'class) is
begin
foo(some);
end test;
begin
null;
end X;
--------
with X;
procedure Main is
B : X.B;
A : X.A;
begin
X.test(B);
X.test(A);
null;
end;
Программа выдает:
foo B
0
foo A
0
On Fri, 6 Mar 2009 11:24:46 +0300, you wrote:
Почему процедура-метод вызывается с "чужим" умолчательным значением?
Потому, что умолчание - свойство самой операции, а не значений ее аргументов. Вполне очевидно, что наличие или отсутствие аргумента не может быть значением оного. Это - к "философии" вопроса.
package X is
type A is tagged null record;
procedure foo ( Self : in A; num : Integer := 0);
type B is new A with null record;
procedure foo (Self: in B; num : Integer := 10);
procedure test (some : A'class);
end X;
with Ada.Text_IO; use Ada.Text_IO;
package body X is
procedure foo ( Self : in A; num : Integer := 0) is
begin
Put_Line("foo A");
Put_Line(Integer'Image(num));
end foo;
procedure foo (Self: in B; num : Integer := 10) is
begin
Put_Line("foo B");
Put_Line(Integer'Image(num));
end foo;
procedure test (some : A'class) is
begin
foo(some);
end test;
begin
null;
end X;
--------
with X;
procedure Main is
B : X.B;
A : X.A;
begin
X.test(B);
X.test(A);
null;
end;
Программа выдает:
foo B
0
foo A
0
Вы вызываете foo объявленную на классе A. Это - одна и та же операция независимо от значения ее аргумента. Тип аргумента тоже один и тот же. Это
- A'Class. Заметьте, A'Class, A, B - разные типы. Если бы Вы вызывали foo из класса B'Class или foo для B, тогда умолчанием было бы 10:
Foo (B'Class (Some)); -- Здесь 10
Foo (B (Some));
...
А вообще, переопределять умолчание - злобно. Не понимаю, почему это вообще разрешено. Менее опасна ситуация с именами параметров. Их тоже можно менять и попадать в забавные истории если использовать ключевую нотацию. При желании можно получить массу удовольствий:
type A is tagged null record;
procedure Foo (X : A; Y : Integer; Z : Integer);
type B is new A with null record;
procedure Foo (X : B; Z : Integer; Y : Integer);
Foo (X => Object, Y => 1, Z => 2); -- Enjoy!
Многие верят, что ключевая нотация "безопаснее" позиционной, нате! (:-))
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Чтобы оставить новое сообщение необходимо Зарегистрироваться и Войти