如何在fortran中正确定义用户定义复数的算术运算符重载?
我的IDE是:代码::Blocks 20.03(MinGW 9.2.0) 这是我的简单代码:如何在fortran中正确定义用户定义复数的算术运算符重载?,fortran,gfortran,Fortran,Gfortran,我的IDE是:代码::Blocks 20.03(MinGW 9.2.0) 这是我的简单代码: module mod_kompleks use, intrinsic :: iso_c_binding, only : rp => c_double implicit none type, public :: kom_bro private real(rp) :: dio_rea real(rp) :: dio_img contains
module mod_kompleks
use, intrinsic :: iso_c_binding, only : rp => c_double
implicit none
type, public :: kom_bro
private
real(rp) :: dio_rea
real(rp) :: dio_img
contains
procedure, private :: kom_bro_sab ! 16 line
generic, public :: operator(+) => kom_bro_sab ! 18 line
end type kom_bro
interface kom_bro
module procedure :: kom_bro_set
end interface kom_bro
contains
! procedure - kom_bro_set
type(kom_bro) function kom_bro_set(rea_part, img_part) result(bro_c)
real, intent(in) :: rea_part, img_part
bro_c%dio_rea = rea_part
bro_c%dio_img = img_part
end function kom_bro_set
! procedure - kom_bro_sab
function kom_bro_sab(bro_a, bro_b) result(bro_c)
type(kom_bro), intent(in) :: bro_a
type(kom_bro), intent(in) :: bro_b
type(kom_bro) :: bro_c
bro_c%dio_rea = bro_a%dio_rea + bro_b%dio_rea
bro_c%dio_img = bro_a%dio_img + bro_b%dio_img
end function kom_bro_sab
end module mod_kompleks
program kompleksni_broj
use, non_intrinsic :: mod_kompleks
implicit none
integer :: i
type(kom_bro) :: broj_01(3)
type(kom_bro) :: broj_02(3)
type(kom_bro) :: broj_03(3)
do i = 1, 3
broj_01(i) = kom_bro(i + 2.2,i + 3.3)
broj_02(i) = kom_bro(i + 4.4,i + 5.5)
broj_03(i) = broj_01(i) + broj_02(i)
end do
end program kompleksni_broj
我打算定义一个看起来像复数的用户类型,但也允许对两个复数进行加法运算。由于在我的示例中我对编程语言Fortran没有经验,因此遇到了一个问题,编译器向我报告以下错误:
| 16 |错误:“kom_bro_sab”的非多态传递对象伪参数
| 18 |错误:未定义特定绑定“kom_bro_sab”作为泛型“+”的目标
| |===生成失败:2个错误,0个警告(0分钟,0秒))=====
我在编程语言Fortran中的OOP知识不足以让我自己解决这个问题。
甚至可以定义这样一个用户定义的类型吗?您有多个错误。最重要的是,运算符重载是错误的。请参见下面的示例实现 复数的派生数据类型(文件名
b.f90
)
模块模块模块
使用,内在::iso_c_绑定,仅:rp=>c_-double
隐式无
私有的
公墓
公共操作员(+)
kom_bro型
私有的
雷亚尔(rp):迪奥·雷亚
雷亚尔(rp):迪奥·伊姆
包含
过程::init=>kom_bro_init
程序::打印=>kom_bro_打印
端型
接口运算符(+)
模块程序kom_bro_sab
端接口
接口kom_bro
模块程序kom_bro_init2
端接口
包含
函数kom_bro_init2(rea_部分,img_部分)结果(bro)
真实(rp)、意图(in):真实部分
真实(rp),意图(in)::img\U部分
类型(kom_bro)::bro
呼叫兄弟%init(真实部分、模拟部分)
端函数
子程序kom_bro_init(此,rea_部分,img_部分)
等级(kom_bro),意图(out)::此
真实(rp)、意图(in):真实部分
真实(rp),意图(in)::img\U部分
此%dio_rea=rea_零件
此%dio\u img=img\u零件
结束子程序
子程序kom_bro_print(本)
类(kom_bro),意图(in)::本
打印*,此%dio\u rea,此%dio\u img
结束子程序
函数kom_bro_sab(bro_a,bro_b)结果(bro_c)
类型(kom_bro),意图(in)::bro_a
类型(kom_bro),意图(in)::bro_b
类型(kom_bro)::bro_c
兄弟c%dio\U rea=兄弟a%dio\U rea+兄弟b%dio\U rea
兄弟c%dio\U img=兄弟a%dio\U img+兄弟b%dio\U img
端函数
端模块
程序(文件名a.f90
)
程序kompleksni_broj
使用mod_kompleks
使用,内在::iso_c_绑定,仅:rp=>c_-double
隐式无
整数::i
类型(kom_bro):broj_01(3)、broj_02(3)、broj_03(3)
i=1,3吗
呼叫broj_01(i)%init(i+2.2\u rp,i+3.3\u rp)!通过类型绑定例程初始化
broj_02(i)=kom_bro(i+4.4_rp,i+5.5_rp)!通过接口kom_bro(又名“类型构造函数”)初始化
broj_03(i)=broj_01(i)+broj_02(i)
致电broj_03(i)%print()
结束
结束程序
输出
$gfortran-g3-Wall-fcheck=所有b.f90 a.f90&./a.out
3.2000000000000002 5.4000000000000004 8.6000000000000014
4.2000000000000002 6.4000000000000004 10.600000000000001
5.2000000000000002 7.4000000000000004 12.600000000000001
您有多个错误。最重要的是,运算符重载是错误的。请参见下面的示例实现
复数的派生数据类型(文件名b.f90
)
模块模块模块
使用,内在::iso_c_绑定,仅:rp=>c_-double
隐式无
私有的
公墓
公共操作员(+)
kom_bro型
私有的
雷亚尔(rp):迪奥·雷亚
雷亚尔(rp):迪奥·伊姆
包含
过程::init=>kom_bro_init
程序::打印=>kom_bro_打印
端型
接口运算符(+)
模块程序kom_bro_sab
端接口
接口kom_bro
模块程序kom_bro_init2
端接口
包含
函数kom_bro_init2(rea_部分,img_部分)结果(bro)
真实(rp)、意图(in):真实部分
真实(rp),意图(in)::img\U部分
类型(kom_bro)::bro
呼叫兄弟%init(真实部分、模拟部分)
端函数
子程序kom_bro_init(此,rea_部分,img_部分)
等级(kom_bro),意图(out)::此
真实(rp)、意图(in):真实部分
真实(rp),意图(in)::img\U部分
此%dio_rea=rea_零件
此%dio\u img=img\u零件
结束子程序
子程序kom_bro_print(本)
类(kom_bro),意图(in)::本
打印*,此%dio\u rea,此%dio\u img
结束子程序
函数kom_bro_sab(bro_a,bro_b)结果(bro_c)
类型(kom_bro),意图(in)::bro_a
类型(kom_bro),意图(in)::bro_b
类型(kom_bro)::bro_c
兄弟c%dio\U rea=兄弟a%dio\U rea+兄弟b%dio\U rea
兄弟c%dio\U img=兄弟a%dio\U img+兄弟b%dio\U img
端函数
端模块
程序(文件名a.f90
)
程序kompleksni_broj
使用mod_kompleks
使用,内在::iso_c_绑定,仅:rp=>c_-double
隐式无
整数::i
类型(kom_bro):broj_01(3)、broj_02(3)、broj_03(3)
i=1,3吗
呼叫broj_01(i)%init(i+2.2\u rp,i+3.3\u rp)!通过类型绑定例程初始化
broj_02(i)=kom_bro(i+4.4_rp,i+5.5_rp)!通过接口kom_bro(又名“类型构造函数”)初始化
broj_03(i)=broj_01(i)+broj_02(i)
致电broj_03(i)%print()
结束
结束程序
输出
$gfortran-g3-Wall-fcheck=所有b.f90 a.f90&./a.out
3.2000000000000002 5.4000000000000004 8.6000000000000014
4.2000000000000002 6.4000000000000004 10.600000000000001
5.2000000000000002 7.4000000000000004 12.600000000000001
这是我写的代码,有点乱,但它显示了我认为您所追求的
ian@eris:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ian@eris:~/work/stack$ cat poly.f90
module mod_kompleks
use, intrinsic :: iso_c_binding, only : rp => c_double
implicit none
type, public :: kom_bro
private
real(rp) :: dio_rea
real(rp) :: dio_img
contains
Procedure, private :: kom_bro_sab ! 16 line
Procedure, Public :: print => kom_bro_print
Procedure, Public :: set => kom_bro_set
generic, public :: operator(+) => kom_bro_sab ! 18 line
end type kom_bro
!!$ interface kom_bro
!!$
!!$ module procedure :: kom_bro_set
!!$
!!$ end interface kom_bro
Private
contains
! procedure - kom_bro_set
!!$ type(kom_bro) function kom_bro_set(rea_part, img_part) result(bro_c)
Subroutine kom_bro_set( bro_c, rea_part, img_part)
Class( kom_bro ), Intent( InOut ) :: bro_c
real, intent(in) :: rea_part, img_part
bro_c%dio_rea = rea_part
bro_c%dio_img = img_part
!!$ end function kom_bro_set
end Subroutine kom_bro_set
! procedure - kom_bro_sab
function kom_bro_sab(bro_a, bro_b) result(bro_c)
Class(kom_bro), intent(in) :: bro_a
Class(kom_bro), intent(in) :: bro_b
Class(kom_bro), Allocatable :: bro_c
! Allocate the return value to the same type as
! one of the provided arguments - may have to modify this depending
! on requirements
Allocate( bro_c, Mold = bro_a )
bro_c%dio_rea = bro_a%dio_rea + bro_b%dio_rea
bro_c%dio_img = bro_a%dio_img + bro_b%dio_img
end function kom_bro_sab
Subroutine kom_bro_print( bro_a )
Class( kom_bro ), Intent( In ) :: bro_a
Write( *, * ) 'Real: ', bro_a%dio_rea, ' Imag: ', bro_a%dio_img
End Subroutine kom_bro_print
end module mod_kompleks
program kompleksni_broj
use, non_intrinsic :: mod_kompleks
implicit none
integer :: i
type(kom_bro) :: broj_01(5)
type(kom_bro) :: broj_02(5)
type(kom_bro) :: broj_03(5)
do i = 1, 5
!!$ broj_01(i) = kom_bro(i + 2.2,i + 3.3)
!!$ broj_02(i) = kom_bro(i + 4.4,i + 5.5)
Call broj_01(i)%set(i + 2.2,i + 3.3)
Call broj_02(i)%set(i + 4.4,i + 5.5)
broj_03(i) = broj_01(i) + broj_02(i)
Write( *, * ) i
Call broj_01(i)%print
Write( *, * ) i
Call broj_02(i)%print
Write( *, * ) i
Call broj_03(i)%print
Write( *, * )
end do
end program kompleksni_broj
ian@eris:~/work/stack$ gfortran -std=f2008 -Wall -Wextra -fcheck=all poly.f90
ian@eris:~/work/stack$ ./a.out
1
Real: 3.2000000476837158 Imag: 4.3000001907348633
1
Real: 5.4000000953674316 Imag: 6.5000000000000000
1
Real: 8.6000001430511475 Imag: 10.800000190734863
2
Real: 4.1999998092651367 Imag: 5.3000001907348633
2
Real: 6.4000000953674316 Imag: 7.5000000000000000
2
Real: 10.599999904632568 Imag: 12.800000190734863
3
Real: 5.1999998092651367 Imag: 6.3000001907348633
3
Real: 7.4000000953674316 Imag: 8.5000000000000000
3
Real: 12.599999904632568 Imag: 14.800000190734863
4
Real: 6.1999998092651367 Imag: 7.3000001907348633
4
Real: 8.3999996185302734 Imag: 9.5000000000000000
4
Real: 14.599999427795410 Imag: 16.800000190734863
5
Real: 7.1999998092651367 Imag: 8.3000001907348633
5
Real: 9.3999996185302734 Imag: 10.500000000000000
5
Real: 16.599999427795410 Imag: 18.800000190734863
ian@eris:~/work/stack$
这是我写的代码有点乱,