Я довольно новичок в Fortran OOP, и перед инициализацией родительских и производных типов я столкнулся с некоторыми проблемами. У меня есть один модуль, содержащий родительский тип object
(извините за чрезмерное использование слова ..) и его производный тип circle
, у которого есть дополнительное поле radius
.Производные типы и конструкции расширенного типа
Способ, которым мне нужно инициализировать тип object
, теперь требует использования фиктивного аргумента радиуса, которого я бы хотел избежать. Итак, на данный момент у меня есть работы, но я хотел бы знать, как это сделать, так как это не кажется очень практичным, если мне нужно будет иметь дополнительные производные типы от object
в будущем.
Я думаю, что использование в качестве абстрактного родительского типа object
поможет в этом смысле? Или используя общие процедуры, но я действительно не знаю, как это сделать.
Код приведен ниже.
module objectMod
implicit none
type :: object
real,allocatable :: x(:,:) ! position vector (points) --- (M,{i,j})
real :: centre(2) ! centre of the object
integer :: M=50 ! number of Lagrangian points of the object (default)
real :: eps=0.1 ! kernel of the surface (default)
contains
procedure :: init=>init_object
end type object
contains
subroutine init_object(a,centre,radius,M,eps)
implicit none
class(object),intent(inout) :: a
real,intent(in) :: centre(2)
integer,intent(in),optional :: M
real,intent(in),optional :: eps
real,intent(in),optional :: radius ! ignored for object
if(present(M)) a%M = M
if(.not.allocated(a%x)) allocate(a%x(a%M,2))
a%centre = centre
if(present(eps)) a%eps = eps
end subroutine init_object
end module objectMod
module geomMod
use objectMod
implicit none
real,parameter :: PI = 3.14159265
type,extends(object) :: circle
real :: radius ! radius
contains
procedure :: init=>init_circle
end type circle
contains
subroutine init_circle(a,centre,radius,M,eps)
implicit none
class(circle),intent(inout) :: a
real,intent(in) :: centre(2)
real,intent(in),optional :: radius
integer,intent(in),optional :: M
real,intent(in),optional :: eps
integer :: i
real :: dtheta
! object type attributes initialization
a%centre = centre
if(present(M)) a%M = M
if(.not.allocated(a%x)) allocate(a%x(a%M,2))
if(present(eps)) a%eps = eps
! circle type attributes initialization
a%radius = radius
dtheta = 2.*PI/real(a%M-1)
do i = 1,a%M
a%x(i,1) = a%radius*cos(dtheta*(i-1))+a%centre(1)
a%x(i,2) = a%radius*sin(dtheta*(i-1))+a%centre(2)
end do
end subroutine init_circle
end module geomMod
Я не могу сбросить радиус, потому что тогда я получаю ошибку несоответствия аргументов (очевидно, я пробовал это). По fancier я имею в виду способ не нуждаться в фиктивных аргументах для родительского конструктора, поскольку он станет неприятным, поскольку я добавляю все больше и больше расширенных типов «объекта». И иногда мне нужно создать экземпляр «объекта». –
Я действительно использовал этот источник, чтобы закодировать это. Поиск там «проигнорирован для формы», поскольку это часть кода, который я фактически использую, и который требует использования фиктивных аргументов для родительских типов. –