スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Fortran2003初心者日記1

Fortran 2003ではオブジェクト指向の機能が使えるそうです。classを使ってプログラムを書いてみました。まだ継承は使ってません。

MODULE class_Foo
IMPLICIT NONE
PRIVATE
PUBLIC :: Foo

!! Type
TYPE :: Foo
PRIVATE
INTEGER :: iii = 0

CONTAINS
PROCEDURE, PUBLIC :: bar => Foo__bar
FINAL :: Foo__destructor
END TYPE Foo

!! Type overloading
INTERFACE Foo
MODULE PROCEDURE Foo__constructorA
MODULE PROCEDURE Foo__constructorB
MODULE PROCEDURE Foo__createA
MODULE PROCEDURE Foo__createB
END INTERFACE Foo

CONTAINS

!! Constructors
SUBROUTINE Foo__constructorA(this, iii)
TYPE(Foo), INTENT(INOUT) :: this
INTEGER, INTENT(IN) :: iii

PRINT *, " Foo__constructorA begin"
this%iii = iii
PRINT *, " Foo__constructorA end"
END SUBROUTINE Foo__constructorA

SUBROUTINE Foo__constructorB(this, i1, i2)
TYPE(Foo), INTENT(INOUT) :: this
INTEGER, INTENT(IN) :: i1
INTEGER, INTENT(IN) :: i2

PRINT *, " Foo__constructorB begin"
this%iii = i1 + i2
PRINT *, " Foo__constructorB end"
END SUBROUTINE Foo__constructorB

TYPE(Foo) FUNCTION Foo__createA(iii) RESULT(this)
INTEGER, INTENT(IN) :: iii

PRINT *, " Foo__createA begin"
CALL Foo__constructorA(this, iii)
PRINT *, " Foo__createA end"
END FUNCTION Foo__createA

TYPE(Foo) FUNCTION Foo__createB(i1, i2) RESULT(this)
INTEGER, INTENT(IN) :: i1
INTEGER, INTENT(IN) :: i2

PRINT *, " Foo__createB begin"
CALL Foo__constructorB(this, i1, i2)
PRINT *, " Foo__createB end"
END FUNCTION Foo__createB

!! Destructor
SUBROUTINE Foo__destructor(this)
TYPE(Foo), INTENT(INOUT) :: this

this%iii = this%iii + 1
PRINT *, " Foo__destructor ", this%iii
END SUBROUTINE Foo__destructor

!! Method
SUBROUTINE Foo__bar(this, iii)
CLASS(Foo), INTENT(INOUT) :: this
INTEGER, INTENT(IN) :: iii

PRINT *, "Foo__bar"
this%iii = iii
END SUBROUTINE Foo__bar

END MODULE class_Foo

SUBROUTINE hoge
USE class_Foo
IMPLICIT none

TYPE(Foo) :: f1
TYPE(Foo) :: f2
TYPE(Foo) :: f3
TYPE(Foo) :: f4

PRINT *, "*** hoge begin"
PRINT *, "f1 = Foo(10)"
f1 = Foo(10)
PRINT *, "f2 = Foo(20, 30)"
f2 = Foo(20, 30)
PRINT *, "CALL Foo(f3, 6000)"
CALL Foo(f3, 6000)
PRINT *, "CALL Foo(f4, 7000, 8000)"
CALL Foo(f4, 7000, 8000)
PRINT *, "f*%bar(5*0)"
CALL f1%bar(510)
CALL f2%bar(520)
CALL f3%bar(530)
CALL f4%bar(540)
PRINT *, "*** hoge end"
END SUBROUTINE hoge

PROGRAM main
USE class_Foo
IMPLICIT none

TYPE(Foo) :: f1
TYPE(Foo) :: f2
TYPE(Foo) :: f3
TYPE(Foo) :: f4

CALL hoge()

PRINT *, "*********"
PRINT *, "f1 = Foo(10)"
f1 = Foo(10)
PRINT *, "f2 = Foo(20, 30)"
f2 = Foo(20, 30)
PRINT *, "CALL Foo(f3, 6000)"
CALL Foo(f3, 6000)
PRINT *, "CALL Foo(f4, 7000, 8000)"
CALL Foo(f4, 7000, 8000)
PRINT *, "f*%bar(5*0)"
CALL f2%bar(510)
CALL f3%bar(520)
CALL f4%bar(530)
CALL f1%bar(540)
END PROGRAM main

このコードはgfortranではコンパイルできませんでした(FINALが未サポートらしい)。
PGIコンパイラでコンパイルした実行結果と、Intelコンパイラでコンパイルした実行結果が異なっていたので、両方載せておきます。今回はコンパイラオプションを何も指定せずにコンパイルしましたが、オプションを変えると挙動が変わったりするのかなぁ?

実行結果(PGIコンパイラ使用)

*** hoge begin
f1 = Foo(10)
Foo__createA begin
Foo__constructorA begin
Foo__constructorA end
Foo__createA end
f2 = Foo(20, 30)
Foo__createB begin
Foo__constructorB begin
Foo__constructorB end
Foo__createB end
CALL Foo(f3, 6000)
Foo__constructorA begin
Foo__constructorA end
CALL Foo(f4, 7000, 8000)
Foo__constructorB begin
Foo__constructorB end
f*%bar(5*0)
Foo__bar
Foo__bar
Foo__bar
Foo__bar
*** hoge end
Foo__destructor 511
Foo__destructor 521
Foo__destructor 531
Foo__destructor 541
*********
f1 = Foo(10)
Foo__createA begin
Foo__constructorA begin
Foo__constructorA end
Foo__createA end
f2 = Foo(20, 30)
Foo__createB begin
Foo__constructorB begin
Foo__constructorB end
Foo__createB end
CALL Foo(f3, 6000)
Foo__constructorA begin
Foo__constructorA end
CALL Foo(f4, 7000, 8000)
Foo__constructorB begin
Foo__constructorB end
f*%bar(5*0)
Foo__bar
Foo__bar
Foo__bar
Foo__bar


実行結果(Intelコンパイラ使用)

*** hoge begin
f1 = Foo(10)
Foo__createA begin
Foo__constructorA begin
Foo__constructorA end
Foo__createA end
Foo__destructor 1
Foo__destructor 11
f2 = Foo(20, 30)
Foo__createB begin
Foo__constructorB begin
Foo__constructorB end
Foo__createB end
Foo__destructor 1
Foo__destructor 51
CALL Foo(f3, 6000)
Foo__constructorA begin
Foo__constructorA end
CALL Foo(f4, 7000, 8000)
Foo__constructorB begin
Foo__constructorB end
f*%bar(5*0)
Foo__bar
Foo__bar
Foo__bar
Foo__bar
*** hoge end
Foo__destructor 511
Foo__destructor 521
Foo__destructor 531
Foo__destructor 541
*********
f1 = Foo(10)
Foo__createA begin
Foo__constructorA begin
Foo__constructorA end
Foo__createA end
Foo__destructor 1
Foo__destructor 11
f2 = Foo(20, 30)
Foo__createB begin
Foo__constructorB begin
Foo__constructorB end
Foo__createB end
Foo__destructor 1
Foo__destructor 51
CALL Foo(f3, 6000)
Foo__constructorA begin
Foo__constructorA end
CALL Foo(f4, 7000, 8000)
Foo__constructorB begin
Foo__constructorB end
f*%bar(5*0)
Foo__bar
Foo__bar
Foo__bar
Foo__bar

メソッドのオーバーロードは、どうやって書けばいいんだろう?
スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

カネダック

Author:カネダック
 
普通のC++プログラマですが、業務で流体解析をやっていて格子職人と呼ばれています。
J.S.バッハ等、古楽をピリオド楽器による演奏で聴くのが好き。
リュート演奏にあこがれつつ、クラシックギターを弾きます。

保有資格
・中小企業診断士
・Oracle Master 8 Platinum(今のGold相当)

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。