next up previous contents
След.: Родовые интерфейсы и переопределение Выше: Интерфейсы Пред.: Родовые интерфейсы и родовые   Содержание


Родовые интерфейсы и перегрузка операторов

Есть возможность определения (перегрузки) операторов: в этом случае вместо родового имени указывается OPERATOR(символ), где символ -- один из встроенных операторов выражений Фортрана или свой символ. Синонимичные операторы сравнения остаются таковыми, например, < и .LT. -- одно и то же, даже если определен только один из них. Свой символ оператора имеет вид .буквы., где буквы -- последовательность букв. В любом случае все описанные процедуры должны быть функциями с одним или двумя аргументами: в первом случае определяется унарный префиксный оператор, во втором -- бинарный инфиксный. Аргументы должны быть входящими. Если переопределяется стандартный оператор, число аргументов должно соответствовать, а их тип должен отличаться от стандартных типом, разновидностью типа, и/или рангом. Определеять операторы можно как для производных, так и для встроенных типов. Пример [14]:

INTERFACE OPERATOR(*)

FUNCTION BOOLEAN_AND(B1, B2)

LOGICAL, INTENT(IN) :: B1(:), B2(SIZE(B1))

LOGICAL :: BOOLEAN_AND(SIZE(B1))

END FUNCTION BOOLEAN_AND

END INTERFACE OPERATOR(*)

Это позволяет осуществлять логическую операцию «И» с операндами логического типа (скалярами или массивами поэлементно) с помощью оператора умножения *:

SENSOR (1:N) * ACTION (1:N)

Возможен и вызов функции:

BOOLEAN_AND(SENSOR(1:N), ACTION(1:N))

Аналогично можно определять и оператор присваивания, указав ASSIGNMENT(=) вместо родового имени (НЕ OPERATOR(=)!). При этом все процедуры, указанные в интерфейсе, должны быть процедурами с двумя аргументами. Аргументы не могут быть необязательными, первый -- исходящий или INTENT(INOUT), второй -- входящий. Либо ранги аргументов должны быть различны, либо типы не должны быть совместимы (в противном случае применимо присваивание по умолчанию), либо первый аргумент имеет производный тип. Оператор присваивания трактуется как вызов процедуры, причем левая часть является первым аргументом, а правая -- вторым.

Пример [14]:

INTERFACE ASSIGNMENT(=)

SUBROUTINE LOGICAL2NUMERIC(N,B)

INTEGER, INTENT(OUT) :: N

LOGICAL, INTENT(IN) :: B

END SUBROUTINE LOGICAL2NUMERIC

END INTERFACE ASSIGNMENT(=) После возможно присваивание

KOUNT = SENSOR(J)

Процедура, второй аргумент которой размещаемый или указатель, не может быть вызвана через присваивание, даже если она указана в соответствующем родовом интерфейсном блоке.



Ilya A. Chernov 2012-12-19
X