4

我正在将某个类的变量复制到同一类的另一个中。编译器很乐意编译它,但我担心在运行时动态类型可能会有所不同。我是否需要测试这两个对象是否具有相同的动态类型以防止在正方形中复制矩形,或者我可以信任编译器吗?如果一个矩形被意外复制到一个正方形中会发生什么?

我想做的是以下几点:

type :: simVars
        class(stateVars), dimension(:), allocatable :: svars
        integer                                     :: count_
    contains
        procedure :: init    => init_simVars
        procedure :: destroy => dest_simVars
        procedure :: add     => add_to_simVars              ! adds an observation to the time series
end type simVars

subroutine init_simVars(this,n)
!--> VERSION 1
    class(simVars), intent(inout) :: this
    integer,        intent(in)    :: n

    allocate( this%svars(n) )

    this%count_ = 0
end subroutine init_simVars

subroutine init_simVars(this,n,sVarsIni)
!--> VERSION 2
    class(simVars), intent(inout) :: this
    integer,        intent(in)    :: n
    class(stateVars), intent(in)  :: sVarsIni

    allocate( this%svars(n),source=sVarsIni )

    this%count_ = 0
end subroutine init_simVars

subroutine add_to_simvars(this,svars)
    class(simVars),   intent(inout) :: this
    class(stateVars), intent(in)    :: svars

    this%count_ = this%count_+1

    this%svars(this%count_) = svars
end subroutine add_to_simvars

subroutine doSimulation(simHist,sVarsIni)
    class(simVars),   intent(out) :: simHist
    class(stateVars), intent(in)  :: sVarsIni
         !--> dynamic type 'stateVars1'

    class(stateVars), allocatable :: sVars   ! will be source allocated from 'iniState'

    ! initialize the state of the economy
    allocate( sVars, source=sVarsIni )    ! "copies" 'sVarsIni' in 'sVars'

    ! initialize 'simHist'
    !--> VERSION 1:
    call simHist%init(nYears)
    !--> VERSION 2:
    call simHist%init(nYears,iniState)

    ! save today's variables
    call simHist%add(sVars)
    ...
end subroutine doSimulation

编译器(ifort 14)很高兴地编译了这两个版本,但我强烈怀疑 VERSION 1 是错误的。ininit_simVars this%svars将被分配给 dynamic type stateVars, inadd_to_simvars sVars将具有动态类型,并且将尝试stateVars1复制 in this%sVars(of type )。stateVars我很惊讶编译器编译它,即使它无法确定sVarsin的动态类型add_to_simvars。运行时会发生什么,段错误或什么?

版本 2 我认为是正确的,但是我有点不愿意相信这里的编译器,因此我认为我应该ASSERT这样做this%sVars并且sVars具有相同的动态类型(ASSERT(SAME_TYPE_AS(this%sVars, sVars) ))?这是一个真正的问题还是我太担心了?

另一个问题是当我这样做时会发生什么allocate( this%svars(n),source=sVarsIni )。我想将数组分配this%sVars为大小n和动态类型sVarsIni。然而sVarsIni是一个标量。它会做我想做的事吗?

4

1 回答 1

2

区别在于这些行

allocate( this%svars(n) )

对比

allocate( this%svars(n),source=sVarsIni )

其中this%svarsclass(svars)可分配数组,svarsIni 是一个class(stateVars)虚拟参数。

这确实改变了很多。

在第一种情况下,它将它分配给声明的类型,即svars,在另一种情况下,它分配给虚拟参数的动态类型,至少是stateVars

如果您使用版本 1,它应该会失败add_to_simvars,因为动态类型将不匹配。

我不知道你是否超载了那里的作业。如果你不这样做,它甚至不应该编译,因为多态对象的内在分配。

于 2014-08-12T12:28:01.250 回答