关于oop:类型绑定过程封装

Type bound procedure encapsulation

如何传递封装的类型绑定函数?我使用了 Modern Fortran Explained 书中的例子(Metcalf、Reid 和 Cohen),这就是我所做的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 module mod_polynoms_abstract

  use mod_geometrics

  implicit none

  type, abstract :: bound_user_polynom
   ! No data
   contains
    procedure(user_polynom_interface), deferred :: eval
  end type bound_user_polynom

  abstract interface
    real function user_polynom_interface(poly, pt)
     import :: bound_user_polynom, point
     class(bound_user_polynom)  :: poly
     type(point), intent(in)    :: pt
   end function user_polynom_interface
  end interface

  contains

 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  !Integral driver/chooser function
  real function integral(userfun, options,status)
   class(bound_user_polynom) :: userfun
   integer, intent(in) :: options
   real, intent(out)   :: status

   select case( options )
    case (1)
     integral = first_integral(userfun)
    case (2)
     integral = second_integral(userfun)
    case default
     integral = def_integral(userfun)
   end select

   end function
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  !1. integration
  real function first_integral(userfun)
   class(bound_user_polynom),intent(in) :: userfun
    first_integral= 1.0 * userfun%eval(point(x=2.,y=2.,z=0.))
  end function  
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  !2. integration
  real function second_integral(userfun)
   class(bound_user_polynom),intent(in) :: userfun
    second_integral= 2.0 * userfun%eval(point(x=2.,y=2.,z=0.))
  end function  
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  !default integration
  real function def_integral(userfun)
   class(bound_user_polynom) :: userfun
    def_integral= 0.0 * userfun%eval(point(x=2.,y=2.,z=0.))
  end function  
 end module

这可以编译,但是当我运行该程序时,我得到了不同的结果。
当我调用函数时,可能是这样的:

1
integral_result = integral(poly, 2 , status)

有时我会得到正确的结果,这是用 second_integral(userfun) 计算的
功能。但有时结果是错误的。
该函数无法正确计算 userfun%eval(point(x=2.,y=2.,z=0.)),但我不知道为什么。
这是正确的方法吗?

编辑:

我使用:

COLLECT_GCC=gfortran4.8
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.8.0/lto-wrapper
Ziel:x86_64-unknown-linux-gnu
Konfiguriert mit: ./configure --disable-multilib
线程模型:posix
gcc 版本 4.8.0 (GCC)

userfun%eval(point(x=2.,y=2.,z=0.))的正确结果是0.962435484
所以 integer(poly, 2 , status) 必须给我 1.92487097。
但是当我多次执行该程序时,我得到了:

第一次运行:1.92487097
第二次运行:54877984.0
...:1.92487097
...:2.55142141E 27
... : 4.19146938E 33
...:1.95548379
等等..

编辑2:

类型多项式定义为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type, extends(bound_user_polynom) :: polynom
   real(kind=kind(1.0D0)), allocatable, dimension(:)            :: coeff
   type(monomial),allocatable, dimension(:)   :: monom
 contains
   procedure :: eval => poly_eval
   procedure, private :: p_add
   generic   :: operator(+) => p_add
   procedure, private :: p_subs
   generic   :: operator(-) => p_subs
 end type

!constructor
interface polynom
 module procedure construct_poly
end interface

在我的主程序中我调用:

1
integral_result = integral(p(2), 2 , status)


在 comp.fortan 的帮助下发现错误:

输入:

userfun%eval(point(x=2.,y=2.,z=0.))

我有一个未初始化的变量,它给了我这个奇怪的结果。
其余的代码似乎没有任何问题。

谢谢,
一月