LoginSignup
9
9

More than 5 years have passed since last update.

fortran2003で,オブジェクト指向使ってスタックを作ってみた

Last updated at Posted at 2014-12-17

例として,integer型のスタックを作ってみた

宣言部

フィールドやら,手続きの宣言やら
(2015/1/3修正 以下のprocedureの行)

こんな感じ
module mod_stack
  implicit none
  public

  type :: stack
     private  ! フィールドはprivateに
     integer :: size ! スタックのサイズ
     integer, allocatable :: stack(:)
     integer :: point=0 ! スタックポインタ(そんな名前でしたっけ?)

   contains ! 中に含む手続き,デストラクタを書く
     procedure :: push
     procedure :: pop
     procedure :: get_point
     final :: dest
  end type stack

   interface stack ! コンストラクタらしく呼び出したいので
      module procedure const
   end interface stack

contains
    ! ここから手続き,コンストラクタ,デストラクタの中身を記述
    ...
end module mod_stack

副プログラム部

ここから個別に見ていく.こいつらは上の contains 以下に書けばいい

コンストラクタ

定義
   type(stack) function const(num) result(this)
     implicit none
     integer,intent(in) :: num
     this%size=num
     allocate(this%stack(num))
   end function const

ここは単純に,領域を確保して,できたstackを返すだけ

使い方
  type(stack), pointer :: stack1, stack2
  allocate(stack1, stack2)
  stack1 = stack(10)
  stack2 = stack(2)

コンストラクタについてはこんな感じ  

デストラクタ

定義
   subroutine dest(this)
     implicit none
     type(stack),intent(inout) :: this
     print *, "dest"
     deallocate(this%stack)
   end subroutine dest
使い方
    deallocate(stack1, stack2)

デストラクタは不十分(-Wallつけると警告が出る)だが,スタックは途中で領域解放することも少なそうなので一旦放置.

その他手続き

スタックおなじみのメソッドとか
   subroutine push(s, c)
     implicit none
     class(stack),intent(inout) :: s
     integer,intent(in) :: c
     s%point = s%point + 1
     s%stack(s%point) = c
   end subroutine push

   integer function pop(s)
     implicit none
     class(stack),intent(inout) :: s
     pop = s%stack(s%point)
     s%point = s%point - 1
   end function pop

   integer function get_point(s)
     implicit none
     class(stack),intent(inout) :: s
     get_point = s%point
   end function get_point

class(stack),intent(inout) :: s はダミー変数なようで…

使い方
  call stack1%push(5)  
  stack1%get_point()
  stack1%pop()

引数に実際に記述する必要はなく,%の前の部分を参照するようだ.

使用例と結果

main
program main
  use mod_stack
  implicit none
  type(stack), pointer :: stack1, stack2

  allocate(stack1, stack2)
  stack1 = stack(10)
  stack2 = stack(2)

  call stack1%push(5)
  call stack2%push(1)
  call stack2%push(2)

  print *, stack1%get_point()
  print *, stack2%get_point()

  print *, stack2%pop()
  print *, stack1%pop()
  print *, stack2%pop()

  deallocate(stack1, stack2)
end program main
           1
           2
           2
           5
           1
 dest
 dest

クラス配列を作る(2015/1/3追記)

配列の宣言
  type(stack),allocatable :: stacks(:)  
  allocate(stacks(5))
9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9