Fortran 如何从函数访问父变量

Fortran 如何从函数访问父变量,fortran,Fortran,我有一个pureComp\u t派生类型,其中包含组件Tc和alphaalpha属于alpha\t派生类型。我希望alpha\u t派生类型中定义的过程value,能够访问组件Tc,进行一些额外的计算 module alpha_m type :: alpha_t contains procedure :: value end type type pureComp_t real(8) :: Tc t

我有一个
pureComp\u t
派生类型,其中包含组件
Tc
alpha
alpha
属于
alpha\t
派生类型。我希望
alpha\u 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
,而对代码的修改最少?

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

type a
  type(b) x
end type a
人们通常不会用“parent”来描述
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
real function inner_value(this, outer_x)
  type(inner), intent(in) :: this
  real, intent(in) :: outer_y
  inner_value = ...
end function
在我们的节目中考虑到这一点

use m
type(outer) a
print *, a%x%value()
end
并使
内部值
能够访问
a
的组件。只是为了证实这是没有意义的,那么这个项目呢

use m
type(inner) b
print *, b%value()   ! There's nothing containing b...
end
print *, a%x%value(a%y)
现在,花了很多时间重复这个问题,是时候寻找解决方案了

简单的回答是:如果我们想要访问的值不是类型绑定过程传递的伪参数类型的组件,那么我们必须以某种方式将其放入该过程的作用域中。我们怎么能做到呢

就最少修改而言,可能在模块中

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
real function inner_value(this, outer_x)
  type(inner), intent(in) :: this
  real, intent(in) :: outer_y
  inner_value = ...
end function
所以在节目中

use m
type(inner) b
print *, b%value()   ! There's nothing containing b...
end
print *, a%x%value(a%y)
现在,这可能会变得乏味和容易出错。吃点东西怎么样

print *, a%value_of_inner()
适当地做感兴趣的事情

可选的是,如果组件<代码> alpHaaT<<代码>在“包含在<代码> PueReCuppt < /代码>”的上下文中是没有意义的,可以考虑使用类型扩展。 我不会详细介绍最后两种方法。或者下面,因为它可能有点可怕

考虑
内部
声明

type inner
  type(outer), pointer :: container=>null()
end type inner
然后,
容器
需要简单地(并且正确地…)与
外部
类型和引用的相关实例相关联

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

这将需要大量额外的“安全”和“设置”代码。

所有人从哪里学到坏的
real(8)
habbit?这一定是某个地方有影响的原因。这是一种学校教学习惯。有什么理由禁止这种书写方式吗?禁止?不,不赞成吗?对它并不意味着8字节,也不意味着双精度,某些编译器将拒绝编译它(至少在默认情况下)。把它教给新手尤其有害。谢谢你的详细回答。你建议我使用
print*,一个%value\u of_internal()
,我认为这会迫使我将变量和方法压缩成更具逻辑性的结构,使代码更容易理解。