Учитывая приведенный ниже минимальный рабочий пример, я хотел бы изменить его, чтобы избежать копирования/вставки вызовов
call func_some_calc1(par)
call func_some_calc2(par)
как в main_func_problem1
, так и в main_func_problem2
. В идеале я хочу иметь одну функцию main_func
, которая ведет себя по-разному для входных параметров типа t_parameters_problem1
и t_parameters_problem2
. Я мог бы объявить его параметр par
базового типа class(t_parameters_base)
, но тогда наличие переключателя внутри этой функции в зависимости от фактического типа аргумента (с использованием select type
) архитектурно не очень хорошо.
Чтобы решить эту проблему, я попытался создать procedure
в типе t_parameters_base
, который вызывает эти подпрограммы, чтобы реализовать что-то вроде этого (синтаксис C++):
class t_parameters_base {
virtual void main_func() {
func_some_calc1(this)
func_some_calc2(this)
}
}
class t_parameters_problem1: public t_parameters_base {
virtual void main_func() {
t_parameters_base::main_func();
func_some_calc3_problem1(this);
}
}
Но проблема в том, что эти подпрограммы используют входной параметр этого типа, что приводит к циклической зависимости. Как можно решить эту проблему?
Обновление: обратите внимание, что я действительно хочу сохранить реализацию func_some_calc1
и func_some_calc2
в разных файлах (модуль/классы), поскольку они реализуют очень разную логику, используя некоторые частные функции из своих классов.
module parameters_base
type, public :: t_parameters_base
integer :: n
end type t_parameters_base
end module parameters_base
module parameters_problem1
use parameters_base
implicit none
type, extends(t_parameters_base), public :: t_parameters_problem1
integer :: p1
end type t_parameters_problem1
end module parameters_problem1
module parameters_problem2
use parameters_base
implicit none
type, extends(t_parameters_base), public :: t_parameters_problem2
integer :: p2
end type t_parameters_problem2
end module parameters_problem2
module some_calc1
use parameters_base
implicit none
contains
subroutine func_some_calc1(par)
class(t_parameters_base) :: par
end subroutine func_some_calc1
end module some_calc1
module some_calc2
use parameters_base
implicit none
contains
subroutine func_some_calc2(par)
class(t_parameters_base) :: par
end subroutine func_some_calc2
end module some_calc2
module some_calc3_problem1
use parameters_problem1
implicit none
contains
subroutine func_some_calc3_problem1(par)
type(t_parameters_problem1) :: par
print*, par%p1
end subroutine func_some_calc3_problem1
end module some_calc3_problem1
module some_calc3_problem2
use parameters_problem2
implicit none
contains
subroutine func_some_calc3_problem2(par)
type(t_parameters_problem2) :: par
print*, par%p2
end subroutine func_some_calc3_problem2
end module some_calc3_problem2
module main_problem1
use parameters_problem1
use some_calc1
use some_calc2
use some_calc3_problem1
implicit none
contains
subroutine main_func_problem1(par)
type(t_parameters_problem1) :: par
call func_some_calc1(par)
call func_some_calc2(par)
call func_some_calc3_problem1(par)
end subroutine main_func_problem1
end module main_problem1
module main_problem2
use parameters_problem2
use some_calc1
use some_calc2
use some_calc3_problem2
implicit none
contains
subroutine main_func_problem2(par)
type(t_parameters_problem2) :: par
call func_some_calc1(par)
call func_some_calc2(par)
call func_some_calc3_problem2(par)
end subroutine main_func_problem2
end module main_problem2
program module_test
use parameters_problem1
use parameters_problem2
use main_problem1
use main_problem2
implicit none
type(t_parameters_problem1) :: par1
type(t_parameters_problem2) :: par2
par1%p1 = 1
par2%p2 = 2
call main_func_problem1(par1)
call main_func_problem2(par2)
end program module_test
func_some_calc1, ...
давать короткие конкретные имена, так все будет более понятно. - person Zeus   schedule 22.06.2015t_parameters
и передачи дополнительного пока отдельно. - person Zeus   schedule 22.06.2015func_some_calc
к (абстрактному) базовому типуt_parameters_base
в форме отложенной процедуры с абстрактным интерфейсом. Это должно сработать, но это как бы подразумевает, что подпрограммы вторичны по отношению к объекту параметра. - person Zeus   schedule 22.06.2015