Ada_Ru форум

Обсуждение языка Ада

Параметры по умолчанию и диспетчеризация ("виртуальный" функции).

Оставить новое сообщение

Сообщения

Alexey Veselovsky
Параметры по умолчанию и диспетчеризация ("виртуальный" функции).
2009-03-06 08:24:46

Почему процедура-метод вызывается с "чужим" умолчательным значением?

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

Новое сообщение:
Страницы: 1

Чтобы оставить новое сообщение необходимо Зарегистрироваться и Войти