수색…


파생 된 형식 정의

Fortran 2003은 객체 지향 프로그래밍을 지원합니다. 이 기능을 사용하면 최신 프로그래밍 기술을 활용할 수 있습니다. 파생 된 유형은 다음 형식으로 정의됩니다.

TYPE [[, attr-list] :: ] name [(name-list)]
   [def-stmts]
   [PRIVATE statement or SEQUENCE statement]. . .
   [component-definition]. . .
   [procedure-part]
END TYPE [name]

어디에,

  • attr-list - 속성 지정자의리스트
  • name - 파생 데이터 형의 이름
  • name-list - 쉼표로 구분 된 유형 매개 변수 이름 목록
  • def-stmts - name-list에 명명 된 유형 매개 변수 중 하나 이상의 INTEGER 선언
  • component-definition - 파생 형식의 구성 요소를 정의하는 하나 이상의 형식 선언 문 또는 프로 시저 포인터 문
  • procedure-part - CONTAINS 문 다음에 PRIVATE 문과 하나 이상의 프로 시저 바인딩 문

예:

type shape
    integer :: color
end type shape

유형 절차

클래스와 비슷한 행동을 취하기 위해서는 타입과 관련 프로 시저 (서브 루틴과 함수)가 하나의 모듈에 배치되어야한다 :

예:

module MShape
    implicit none
    private

    type, public :: Shape
    private
        integer :: radius
    contains
        procedure :: set   => shape_set_radius
        procedure :: print => shape_print
    end type Shape

contains
    subroutine shape_set_radius(this, value)
        class(Shape), intent(in out) :: self
        integer, intent(in)          :: value

        self%radius = value
    end subroutine shape_set_radius

    subroutine shape_print(this)
        class(Shape), intent(in) :: self

        print *, 'Shape: r = ', self%radius
    end subroutine shape_print
end module MShape

나중에 코드에서이 Shape 클래스를 다음과 같이 사용할 수 있습니다.

! declare a variable of type Shape
type(Shape) :: shape

! call the type-bound subroutine
call shape%set(10)
call shape%print 

추상 파생 된 유형

확장 가능한 파생 형식은 추상적 일 수 있습니다.

type, abstract :: base_type
end type

이러한 파생 된 유형은 다음과 같이 인스턴스화 할 수 없습니다.

type(base_type) t1
allocate(type(base_type) :: t2)

그러나 다형성 객체는 이것을 선언 된 타입으로 가질 수있다.

class(base_type), allocatable :: t1

또는

function f(t1)
  class(base_type) t1
end function

추상 타입은 컴포넌트와 타입 - 바운드 프로 시저를 가질 수있다.

type, abstract :: base_type
  integer i
contains
  procedure func
  procedure(func_iface), deferred :: def_func
end type

프로 시저 def_func 는 인터페이스 func_iface 가있는 지연된 유형 바인딩 프로 시저입니다. 이러한 지연된 타입 - 바운드 프로시 저는 각각의 확장 타입에 의해 구현되어야한다.

유형 확장

파생 된 유형은 bind 속성이나 sequence 속성이없는 경우 확장 가능 합니다. 이러한 유형은 다른 유형으로 확장 될 수 있습니다.

module mod

  type base_type
    integer i
  end type base_type

  type, extends(base_type) :: higher_type
    integer j
  end type higher_type

end module mod

선언 형와 다형 변수 base_type 유형과 호환 타입 higher_type 그 동적 타입을 가질 수있다

class(base_type), allocatable :: obj
allocate(obj, source=higher_type(1,2))

유형 호환성은 하위 체인을 통해 내려 지나지 만 유형은 한 유형 만 확장 할 수 있습니다.

확장 파생 형은 부모로부터 형식 바인딩 된 프로 시저를 상속 받지만이를 재정의 할 수 있습니다.

module mod

  type base_type
  contains
    procedure :: sub => sub_base
  end type base_type

  type, extends(base_type) :: higher_type
  contains
    procedure :: sub => sub_higher
  end type higher_type

contains

  subroutine sub_base(this)
    class(base_type) this
  end subroutine sub_base

  subroutine sub_higher(this)
    class(higher_type) this
  end subroutine sub_higher

end module mod

program prog
  use mod

  class(base_type), allocatable :: obj

  obj = base_type()
  call obj%sub

  obj = higher_type()
  call obj%sub

end program

유형 생성자

인터페이스를 사용하여 형식 이름을 오버로드하여 파생 형식에 대해 사용자 지정 생성자를 만들 수 있습니다. 이 방법으로, 해당 유형의 오브젝트를 구성 할 때 구성 요소와 일치하지 않는 키워드 인수를 사용할 수 있습니다.

module ball_mod
  implicit none

  ! only export the derived type, and not any of the
  ! constructors themselves
  private
  public :: ball

  type :: ball_t
     real :: mass
  end type ball_t

  ! Writing an interface overloading 'ball_t' allows us to
  ! overload the type constructor
  interface ball_t
     procedure :: new_ball
  end interface ball_t

contains

  type(ball_t) function new_ball(heavy)
    logical, intent(in) :: heavy

    if (heavy) then
       new_ball%mass = 100
    else
       new_ball%mass = 1
    end if
    
  end function new_ball
  
end module ball_mod

program test
  use ball_mod
  implicit none

  type(ball_t) :: football
  type(ball_t) :: boulder
  
  ! sets football%mass to 4.5
  football = ball_t(4.5)
  ! calls 'ball_mod::new_ball'
  boulder = ball_t(heavy=.true.)
end program test

이것은 별도의 초기화 루틴을 사용하는 것보다 깔끔한 API를 만드는 데 사용할 수 있습니다.

subroutine make_heavy_ball(ball)
  type(ball_t), intent(inout) :: ball
  ball%mass = 100
end subroutine make_heavy_ball

...

call make_heavy_ball(boulder)


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow