ООП и Фортран90 - PullRequest
       16

ООП и Фортран90

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

Здравствуйте, я пытаюсь освоить объектно-ориентированное программирование с использованием Fortran (все мои коды написаны на Fortran 90), я частично знаю C ++, но я хочу продолжать использовать Fortran.

В Fortran вы делаете классы, используямодули.При написании оператора integer, parameter :: dp = selected_real_kind(15,307) я сталкиваюсь с ошибками компиляции.Вот мой академический код.Это короткий код, который использует Абстрактные классы

module class_Rectangle
  implicit none
  integer, parameter :: dp = selected_real_kind(15,307)
  type Rectangle
     real(dp) :: a,b
  end type Rectangle
contains
  subroutine area_rectangle(area,info)
    implicit none
    real(dp), intent(out) :: area
    type(Rectangle), intent(in) ::  info

    area = info%a * info%b

  end subroutine area_rectangle
end module class_Rectangle

program Main
  use class_Rectangle
  use class_Circle
  implicit none

  integer, parameter :: dp = selected_real_kind(15,307)

  interface compute_area
     module procedure area_rectangle, area_circle
  end interface compute_area

  type(Rectangle) :: geoA
  type(Circle) :: geoB
  real(dp) :: area

  geoA = Rectangle(2.0d0,4.0d0)
  call area_rectangle(area,geoA)
  write(*,*) 'Rectangle area:', area
  geoB = Circle(1.0d0)
  call area_circle(area,geoB)
  write(*,*) 'Circle area:',area

end program Main

Сообщение, которое компилятор возвращает мне, выглядит следующим образом:

integer, parameter :: dp = selected_real_kind(15,307)
                          1

Ошибка: имя 'dp' в (1) является неоднозначнымссылка на 'dp' из модуля 'class_rectangle' Main.f90: 81.13:

  real(dp) :: area
         1

Ошибка: имя 'dp' в (1) является неоднозначной ссылкой на 'dp' из модуля 'class_rectangle' Main.f90: 84.30:

Любые намеки или советы приветствуются.

Ответы [ 3 ]

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

Просто опустите: целое число, параметр :: dp = selected_real_kind (15,307) в основной программе! ИСПОЛЬЗУЯ class_Rectangle основной программы это разделяет эту переменную с модулем (за исключением того, что вы объявляете ее закрытой, это не то, что вы хотите, я думаю).

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

Всегда старайтесь использовать оператор USE с ONLY. Если вы это сделаете, вы не столкнетесь с ошибкой неоднозначности, которую вы получите. Кроме того, вы будете точно знать, что используется в вашем коде из каждого модуля, просто взглянув на верхние строчки вашего кода. Поэтому заголовок вашей основной программы может выглядеть так:

program Main

use class_Rectangle, only: Rectangle, area_rectangle
use class_Circle, only: Circle, area_circle
implicit none


integer, parameter :: dp = selected_real_kind(15,307)

interface compute_area
        module procedure area_rectangle, area_circle
end interface

type(Rectangle) :: geoA
type(Circle) :: geoB
real(dp) :: area

geoA = Rectangle(2.0d0,4.0d0)
call area_rectangle(area,geoA)
write(*,*) 'Rectangle area:', area
geoB = Circle(1.0d0)
call area_circle(area,geoB)
write(*,*) 'Circle area:',area

end program Main

Хороший учебник по программированию ООП на Фортране с некоторыми хорошими примерами см. В книге «Объяснение современного Фортрана», автор Metcalf et al.

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

В зависимости от вашего компилятора вы должны получать довольно полезные сообщения

module a
end module a

program b
    implicit none
    use a
end program b

и компилировать:

$ gfortran mod_test.F90
mod_test.F90:6:9:

     implicit none
                 2
     use a
         1
Error: USE statement at (1) cannot follow IMPLICIT NONE statement at (2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...