하자 내가 추상의 base class 있다고 가정 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
for dynamic polymorphism이 도입 된 다음 코드 가 확실한 해결 방법입니까? 컴파일 타임에 구체적인 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
일반 인터페이스에서 특정 프로 시저를 선택하고 일반 인터페이스의 특정 프로 시저를 구별 할 수 있어야하는 방법에 대한 Fortran의 규칙은 배우고 적용하기 쉽게 설계되었습니다. "최적 일치"/ "가장 구체적"이 선택되는 방법을 설명하는 규칙이 필요하지 않도록 모호 할 수있는 상황에서 언어 규칙은 최대 하나의 비 요소 절차와 최대 하나가있을 수 있습니다. 모든 범위 지정 단위에서 일치하는 요소 프로 시저 (비 요소 특정이 일치하지 않는 경우에만 요소 세부 사항이 고려 됨).
귀하가 제안한 절차는 이러한 언어 규칙을 위반합니다.
나는 "배우고 적용하기 쉬운"설계 의도를 잃어 버리는 방식으로 규칙을 변경하려는 현실적인 제안을 보지 못했습니다.
get_area에 대한 관련 계산을 구현하는 함수를 지정하는 각 유형에 지연된 바인딩을 넣으십시오. get_shape 함수에서 해당 바인딩으로 전달합니다 (또는 get_shape에 대한 참조를 바인딩에 대한 참조로 변경). SELECT TYPE을 사용하여 유형별 동작을 구현하지 마십시오. 유형별 동작은 바인딩을 사용하여 구현해야합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다