2017-02-28 204 views
2

我有一个pureComp_t派生类型,其组件为Tcalphaalpha是派生类型的alpha_t。我希望在alpha_t派生类型中定义的过程value能够访问组件Tc以进行一些额外的计算。如何从函数访问父变量

module alpha_m 

    type :: alpha_t 
     contains 
      procedure :: value 
    end type 

    type pureComp_t 
     real(8) :: Tc 
     type(alpha_t) :: alpha 
    end type 

contains 

    function value(this,T) 
    implicit none 

     class(alpha_t) :: this 
     real(8) :: T 
     real(8) :: value 

     value = T/this%Tc 

    end function 

end module 

program regression_alpha 

    use alpha_m 
    implicit none 

    type(pureComp_t) :: pureComp 

    pureComp%Tc = 620.d0 
    write(*,*)pureComp%alpha%value(610.d0) 

end program 

现在,我试图通过编写this%Tc越来越可变Tc但函数的参数this显然是指alpha_t派生类型,而不是在purecomp_t派生类型。

我可以通过对代码的最小修改访问变量Tc进行哪些修改?

+0

所有的人都在哪里学习坏的“真实”(8)'习惯?这里肯定有一些有影响力的来源。 –

+0

这是一个学校的教学习惯。这种书写方式应该被禁止吗? – yolegu

+1

禁止?号皱起了眉头?是。它并不意味着8字节,也不意味着双精度,某些编译器会拒绝编译它(至少默认情况下)。教给新手特别有害。 http://stackoverflow.com/documentation/fortran/939/data-types/4390/precision-of-floating-point-numbers#t=201703011100570236545 –

回答

1

首先关于术语的说明:与派生类型相关的“父”通常以类型扩展而不是内容的方式理解。即,在

type a 
    type(b) x 
end type a 

一个一般不会使用“母”来描述之间(的实例)a及其组成x关系。

就这样说吧,让我们继续讨论真正的问题。考虑模块

module m 
    type inner 
    contains 
    procedure :: inner=>inner_value 
    end type inner 

    type outer 
    type(inner) x 
    real :: y=1. 
    end type outer 

contains 

    real function inner_value(this) 
    type(inner), intent(in) :: this 
    inner_value = ... 
    end function 

end module m 

考虑,在我们的计划,我们希望

use m 
type(outer) a 
print *, a%x%value() 
end 

与事让inner_value访问的a组件。只是为了确认这是没有意义的,何谈程序

use m 
type(inner) b 
print *, b%value() ! There's nothing containing b... 
end 

现在,已经花了很多线只是重申这个问题,它的时间来寻找解决方案。

简短的回答是:如果我们想访问一个不是类型组成部分的值,那就是类型绑定过程的传入哑元参数,那么我们必须以某种方式将它包含在该过程的范围内。我们怎么做到这一点?

在条款修改最少的,也许模块

real function inner_value(this, outer_x) 
    type(inner), intent(in) :: this 
    real, intent(in) :: outer_y 
    inner_value = ... 
end function 

这样在程序

print *, a%x%value(a%y) 

在现在,可能变得单调而乏味,而且容易出错。如何拥有

print *, a%value_of_inner() 

对于value_of_inner()适当地做有意义的事情。

或者,如果组件alpha_t在“包含在pureComp_t之内”的上下文之外永远没有意义,可以考虑使用类型扩展。

我不会写出最后两种方法的细节。或者以下,因为它可能有点可怕。

考虑inner声明

type inner 
    type(outer), pointer :: container=>null() 
end type inner 

然后container人只需要(并正确...)可以与outer类型和参考的相关实例像

real function inner_value(this) 
    type(inner), intent(in) :: this 
    inner_value = this%container%y 
end function 

这将需要相关相当数量的额外“安全”和“设置”代码螺栓上。

+0

谢谢你的详细解答。您对使用'print *,%value_of_inner()'的建议有我的偏好,它会迫使我将变量和方法压缩成更多的逻辑结构,使代码更易于理解。 – yolegu