|
本帖最后由 weixing1531 于 2019-4-4 00:09 编辑
由于Fortran没有模板,经常导致编写的算法通用性差 一般的解决方法进行预处理
类似于
#define T integer
T function max(x, y)
T :: x, y
if (x < y) then
max = y
else
max = x
endif
end function
下面介绍另外一种方法——无限多态class(*)
源代码如下(源代码摘自《Modern_Fortran_Explained》第433页,下载地址:ftp://ftp.numerical.rl.ac.uk/pub/MRandC/oo.f90)
[Fortran] 纯文本查看 复制代码 004 | public :: anylist , anyitem , newitem |
007 | class ( anyitem ) , pointer , private :: firstptr = > null ( ) |
009 | procedure , non_overridable :: append |
010 | procedure , non_overridable :: count_list |
011 | procedure , non_overridable :: delete_list |
012 | procedure , non_overridable :: first |
013 | procedure , non_overridable :: last |
014 | procedure , non_overridable :: prepend |
015 | procedure , non_overridable :: print_list |
019 | class ( * ) , allocatable :: value |
020 | class ( anyitem ) , pointer , private :: nextptr = > null ( ) , prevptr = > null ( ) |
021 | class ( anylist ) , pointer , private :: upptr = > null ( ) |
023 | procedure , non_overridable :: change |
024 | procedure , non_overridable :: delete |
025 | procedure , non_overridable :: list |
026 | procedure , non_overridable :: next |
027 | procedure , non_overridable :: prev |
029 | procedure , non_overridable :: remove |
032 | function newitem ( something ) |
033 | class ( * ) , intent ( in ) :: something |
034 | class ( anyitem ) , pointer :: newitem |
036 | allocate ( newitem % value , source = something ) |
037 | newitem % prevptr = > newitem |
040 | subroutine append ( list , item ) |
041 | class ( anylist ) , intent ( inout ) , target :: list |
042 | class ( anyitem ) , target :: item |
043 | class ( anyitem ) , pointer :: last |
045 | if ( associated ( item % upptr ) ) call remove ( item ) |
047 | if ( associated ( list % firstptr ) ) then |
048 | last = > list % firstptr % prevptr |
051 | list % firstptr % prevptr = > item |
053 | list % firstptr = > item |
058 | integer function count_list ( list ) |
059 | class ( anylist ) , intent ( in ) :: list |
060 | class ( anyitem ) , pointer :: p |
064 | if ( .not. associated ( p ) ) exit |
065 | count_list = count_list + 1 |
070 | subroutine delete_list ( list ) |
071 | class ( anylist ) , intent ( inout ) :: list |
073 | if ( .not. associated ( list % firstptr ) ) exit |
074 | call delete ( list % firstptr ) |
079 | class ( anylist ) , intent ( in ) :: list |
080 | class ( anyitem ) , pointer :: first |
081 | first = > list % firstptr |
085 | class ( anylist ) , intent ( in ) :: list |
086 | class ( anyitem ) , pointer :: last |
087 | last = > list % firstptr |
088 | if ( associated ( last ) ) last = > last % prevptr |
091 | subroutine prepend ( list , item ) |
092 | class ( anylist ) , intent ( inout ) , target :: list |
093 | class ( anyitem ) , target :: item |
094 | if ( associated ( item % upptr ) ) call remove ( item ) |
096 | if ( associated ( list % firstptr ) ) then |
097 | item % prevptr = > list % firstptr % prevptr |
098 | item % nextptr = > list % firstptr |
099 | list % firstptr % prevptr = > item |
103 | list % firstptr = > item |
106 | subroutine print_list ( list , show_item_numbers , show_empty_list ) |
107 | class ( anylist ) , intent ( in ) :: list |
108 | logical , intent ( in ) , optional :: show_item_numbers , show_empty_list |
109 | class ( anyitem ) , pointer :: p |
111 | logical :: show_numbers |
112 | if ( present ( show_item_numbers ) ) then |
113 | show_numbers = show_item_numbers |
115 | show_numbers = .true. |
118 | if ( .not. associated ( p ) ) then |
119 | if ( present ( show_empty_list ) ) then |
120 | if ( show_empty_list ) print * , 'List is empty.' |
122 | print * , 'List is empty.' |
126 | if ( show_numbers ) write ( * , 1 , advance = 'no' ) i |
127 | 1 format ( 1 x , 'Item ' , i 0 , ':' ) |
130 | if ( .not. associated ( p ) ) exit |
135 | subroutine change ( item , newvalue ) |
136 | class ( anyitem ) , intent ( inout ) :: item |
137 | class ( * ) , intent ( in ) :: newvalue |
139 | deallocate ( item % value ) |
140 | allocate ( item % value , source = newvalue ) |
143 | subroutine delete ( item ) |
144 | class ( anyitem ) , target :: item |
145 | class ( anyitem ) , pointer :: temp |
152 | class ( anyitem ) , intent ( in ) :: item |
153 | class ( anylist ) , pointer :: list |
158 | class ( anyitem ) , intent ( in ) :: item |
159 | class ( anyitem ) , pointer :: next |
164 | class ( anyitem ) , intent ( in ) :: item |
165 | class ( anyitem ) , pointer :: prev |
169 | subroutine print ( this ) |
170 | class ( anyitem ) , intent ( in ) :: this |
172 | select type ( v = > this % value ) |
173 | type is ( character ( * ) ) |
176 | print 1 , length , v ( : 36 ) |
177 | 1 format ( 1 x , 'character(len=' , i 0 , ') = "' , a , '"...' ) |
179 | print * , 'character = "' , v , '"' |
182 | print * , 'complex' , v |
183 | type is ( complex ( kind ( 0 d 0 ) ) ) |
185 | 2 format ( 1 x , 'complex(kind=' , i 0 , ') = (' , es 23.16 , ', ' , es 23.16 , ')' ) |
186 | type is ( real ( kind ( 0 d 0 ) ) ) |
188 | 3 format ( 1 x , 'real(kind=' , i 0 , ') = ' , es 23.16 ) |
190 | print * , 'integer = ' , v |
192 | print * , 'real = ' , v |
194 | print * , 'logical = ' , v |
196 | print * , 'unrecognised item type - cannot display value' |
200 | subroutine remove ( item ) |
201 | class ( anyitem ) , intent ( inout ) , target :: item |
202 | class ( anylist ) , pointer :: list |
204 | if ( associated ( list ) ) then |
205 | if ( associated ( item % prevptr , item ) ) then |
207 | nullify ( list % firstptr ) |
208 | else if ( .not. associated ( item % nextptr ) ) then |
210 | list % firstptr % prevptr = > item % prevptr |
211 | nullify ( item % prevptr % nextptr ) |
212 | else if ( associated ( list % firstptr , item ) ) then |
214 | list % firstptr = > item % nextptr |
215 | item % nextptr % prevptr = > item % prevptr |
217 | item % prevptr % nextptr = > item % nextptr |
218 | item % nextptr % prevptr = > item % prevptr |
|
评分
-
查看全部评分
|