Перегрузка функций в Fortran 2008 - PullRequest
0 голосов
/ 29 мая 2018

Я начинаю с Фортрана 2008 и очень сильно борюсь с ООП.Кажется, что существует очень мало материалов, которые объясняют очень основные концепции ООП в стандарте языка 2008 года.

Я нашел информацию о наследовании, но не смог найти никакой информации о полиморфизме.

Так что, если я хочу перегрузить функцию в C ++, я могу сделать это следующим образом (пример из Википедии):

// volume of a cube
int volume(const int s)
{
    return s*s*s;
}

// volume of a cylinder
double volume(const double r, const int h)
{
    return 3.1415926*r*r*static_cast<double>(h);
}

// volume of a cuboid
long volume(const long l, const int b, const int h)
{
    return l*b*h;
}

Но как мне сделать то же самое в Fortran 2008?

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

пример расширения Fancescalus:

module Pablo_Dali
private

interface volume_Cube
  module procedure volume_cube_Int, volume_cube_Float, Colume_cube_Double
!add in 8, 16, and 64 bit ints... and complex??
end interface volume
public volume_Cube

contains
  integer function volume_cube_Int(s)
    integer, intent(in) :: s
    volume_cube_Int = s**3
  end function volume_cube_int

  float function volume_cube_Float(s)
    float, intent(in) :: s
    volume_cube_float = s**3
  end function volume_cube_Float

  integer function volume_cube_Double(s)
    DOUBLE, intent(in) :: s
    volume_cube_Double = s**3
  end function volume_cube_Double
end module Pablo_Dali

затем код:

PROGRAM Cube_Volume
USE Pablo_Dali
IMPLICIT NONE

INTEGER :: I_Side, I_Volume
FLOAT   :: F_Side, F_Volume
DOUBLE  :: D_Side, D_Volume

I_Side = 1
F_Side = 1.0E0
D_Side = 1.0D0

WRITE(*,*)'[INT]    ',I_Side,' cubed=', volume_cube(I_Side)
WRITE(*,*)'[FLOAT]  ',F_Side,' cubed=', volume_cube(F_Side)
WRITE(*,*)'[DOUBLE] ',D_Side,' cubed=', volume_cube(D_Side)

END PROGRAM Cube_Volume
0 голосов
/ 29 мая 2018

Идея перегрузки, приведенная в примерах C ++, реализована в Фортране, начиная с обобщений из Фортрана 90.

С учетом набора специфических процедуры, общий идентификатор может быть использован для идентификации этого набора.В этом ответе я дам очень общее введение в эту концепцию.Есть много тонкостей, которые могут потребовать дальнейшего чтения / вопросов для решения.

В отличие от примера C ++, наши специфичные для Fortran процедуры должны называться отдельно.Давайте две функции (третья может быть добавлена ​​ mutatis mutandis )

integer function volume_cube(s)
  integer, intent(in) :: s
  ...
end function volume_cube

double precision function volume_cylinder(r, h)
  double precision, intent(in) :: r
  integer, intent(in) :: h
  ...
end function volume_cylinder

Затем мы можем добавить универсальный интерфейс для чего-то под названием volume:

interface volume
  procedure volume_cube, volume_cylinder
end interface

Затем мы можем сослаться на универсальный volume, и компилятор определит, какую конкретную функцию использовать.

Существует гораздо больше информации о дженериках, включая то, что они предлагают помимо этой простой перегрузки.Следует также понимать, как решаются конкретные процедуры (простые в этом случае, а не в других) и ограничения, на которых конкретные процедуры могут быть объединены.Поскольку вы используете дженерики, проблемные случаи могут вызывать определенные вопросы.Я отвечаю здесь только потому, что не вижу вводного вопроса, и я не пытаюсь ответить на множество различных трудностей или ценностей.


Полный пример

module mod

  private

  interface volume
     module procedure volume_cube, volume_cylinder
  end interface volume
  public volume

contains
  integer function volume_cube(s)
    integer, intent(in) :: s
    volume_cube = s**3
  end function volume_cube

  double precision function volume_cylinder(r, h)
    double precision, intent(in) :: r
    integer, intent(in) :: h
    volume_cylinder = 3.1415926d0*r**2*h
  end function volume_cylinder

end module mod

  use mod

  print*, volume(2), volume(2d0,4)
end
...