例として,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))