【发布时间】:2023-03-17 21:26:01
【问题描述】:
假设我有一个抽象基类Shape_t,派生类型Rectangle_t 和Circle_t。
两种派生类型都有一个通用函数get_area,我想为类重载它,以便获得以下接口(Julianesque 表示法):
get_area(type(Circle_t) :: C)
get_area(type(Rectangle_t) :: R)
! The following leads to ambiguous interfaces
get_area(class(Shape_t) :: S)
不幸的是,当我尝试这个时,我得到了一个“模棱两可的界面”错误。 由此我有三个问题:
我想要实现的目标有什么概念上的错误吗?由于变量被显式声明为多态 (
class(...)),编译器总是可以选择最具体的接口并回退到多态接口。所以我没有看到歧义。如果问题 1 的答案是:“没有概念歧义”。标准中是否有计划对此进行更改?
以下代码(其中引入了用于动态多态性的
dyn_get_area)是一个可靠的解决方法吗?请注意,我想尽可能长时间地坚持静态多态性,即只要具体的 Shape 在编译时是已知的。
module shapes_mod
implicit none
private
public :: Shape_t, Rectangle_t, Circle_t, PI, get_area, dyn_get_area
real, parameter :: PI = atan(1.0) * 4.0
type, abstract :: Shape_t
end type
type, extends(Shape_t) :: Circle_t
real :: r = 0.0
end type
type, extends(Shape_t) :: Rectangle_t
real :: a = 0.0, b = 0.0
end type
interface get_area
module procedure get_area_Rectangle_t, get_area_Circle_t
end interface
contains
pure function get_area_Circle_t(C) result(res)
type(Circle_t), intent(in) :: C
real :: res
res = C%r**2 * PI
end function
pure function get_area_Rectangle_t(R) result(res)
type(Rectangle_t), intent(in) :: R
real :: res
res = R%a * R%b
end function
pure function dyn_get_area(S) result(res)
class(Shape_t), intent(in) :: S
real :: res
select type(S)
type is(Rectangle_t)
res = get_area(S)
type is(Circle_t)
res = get_area(S)
end select
end function
end module
program test_polymorphic_and_static_overload
use shapes_mod, only: Shape_t, Rectangle_t, Circle_t, get_area, dyn_get_area
implicit none
class(Shape_t), allocatable :: random_shape
type(Circle_t) :: circle
type(Rectangle_t) :: rectangle
real :: p
circle = Circle_t(1.0)
rectangle = Rectangle_t(1.0, 2.0)
call random_number(p)
if (p < 0.5) then
random_shape = circle
else
random_shape = rectangle
end if
write(*, *) get_area(circle)
write(*, *) get_area(rectangle)
write(*, *) dyn_get_area(random_shape)
end program
【问题讨论】:
-
这些 #: 宏或指令是什么?
-
@VladimirF,例如,参见fypp.readthedocs.io/en/stable/fypp.html#preprocessor-language。
-
对不起,如果我回到我的电脑前,我会用纯 Fortran 代码替换它。
标签: fortran polymorphism overloading