Cha*_*les 3 oop fortran operator-overloading gfortran
有没有办法重载=运算符,以便您可以编写如下示例中的赋值:
module constants_mod
integer,parameter :: dpn = selected_real_kind(14)
end module
module vectorField_mod
use constants_mod
implicit none
private
public :: vectorField
public :: allocateX,allocateY,allocateZ
public :: delete
! public :: operator(=)
type vectorField
integer,dimension(3) :: sx,sy,sz
real(dpn),dimension(:,:,:),allocatable :: x,y,z
end type
interface delete
module procedure deallocateVectorField
end interface
! interface operator (=)
! module procedure vectorAssign
! end interface
contains
! function vectorAssign(f) result(q)
! implicit none
! real(dpn),intent(in) :: f
! type(vectorField) :: q
! q%x = f; q%y = f; q%z = f
! end function
! subroutine vectorAssign(f,g)
! implicit none
! type(vectorField),intent(inout) :: f
! real(dpn),intent(in) :: g
! f%x = g; f%y = g; f%z = g
! end subroutine
subroutine allocateX(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%x)) deallocate(field%x)
allocate(field%x(Nx,Ny,Nz))
field%sx = shape(field%x)
end subroutine
subroutine allocateY(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%y)) deallocate(field%y)
allocate(field%y(Nx,Ny,Nz))
field%sy = shape(field%y)
end subroutine
subroutine allocateZ(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%z)) deallocate(field%z)
allocate(field%z(Nx,Ny,Nz))
field%sz = shape(field%z)
end subroutine
subroutine deallocateVectorField(field)
implicit none
type(vectorField),intent(inout) :: field
deallocate(field%x,field%y,field%z)
field%sx = 0; field%sy = 0; field%sz = 0
end subroutine
end module
program test
use constants_mod
use vectorField_mod
implicit none
type(vectorField) :: a
integer :: N = 1
real(dpn) :: dt = 0.1
call allocateX(a,N,N,N)
call allocateY(a,N,N,N)
call allocateZ(a,N,N,N)
a%x = dble(1.0) ! want to avoid this
a%y = dble(1.0) ! want to avoid this
a%z = dble(1.0) ! want to avoid this
a = real(1.0,dpn) ! want this instead (does not compile)
call delete(a)
end program
Run Code Online (Sandbox Code Playgroud)
我尝试了两种不同的方式(在注释中显示)但我得到错误,说通用规范中存在语法错误(用于公开=运算符).任何帮助这样做非常感谢!
= 它不是运算符,它是Fortran中的一个赋值,它们是非常不同的动物.
对于在Fortran 90中发现的经典可能性以及在其他答案中得到很好解释,Fortran 2003添加了更好的可能性来将重载的运算符和赋值与派生类型绑定.
这样您就可以确保在没有赋值的情况下不会导入类型(在这种情况下要注意公共和私有语句!).它可能会产生非常不愉快的后果,并且很难调试:
type vectorField
integer,dimension(3) :: sx,sy,sz
real(dpn),dimension(:,:,:),allocatable :: x,y,z
contains
procedure :: assignVector
generic :: assignment(=) => assignVector
end type
Run Code Online (Sandbox Code Playgroud)
这样你就不必小心不要忘记了 public :: assignment (=)
对于定义的赋值operator(=)不正确,而是assignment(=):参见 Fortran 2008 12.4.3.4.3。所以你想要两个肿块
public :: assignment (=)
Run Code Online (Sandbox Code Playgroud)
和
interface assignment (=)
module procedure vectorAssign
end interface
Run Code Online (Sandbox Code Playgroud)
请注意,定义分配的正确方法是通过您拥有的子例程(尽管受让人可以用intent(out)代替intent(inout))。