【问题标题】:How to access private variables in fortran modules?如何访问 fortran 模块中的私有变量?
【发布时间】:2015-09-29 17:05:11
【问题描述】:

我知道私有变量的想法是它们不应该被访问,并且我确实希望它在程序的其余部分中使用该模块时以这种方式工作,但我需要它来检查内部模块的工作原理。

假设我有以下简化示例:

module mod
  implicit none
  private
  integer :: value
  public :: set_value

contains

subroutine set_value(input)
  implicit none
  integer,intent(in) :: input
  value=input
end subroutine

end module

我现在想测试子例程,看看它是否真的在做我想要的:我想编写一个使用该模块的程序,使用输入 8 调用例程 set_value,然后检查内部变量是否value 现在是 8。

我可以这样做吗?还是有另一种方法来对私有变量的初始化程序进行单元测试?

【问题讨论】:

  • 写一个get_value函数并用它来测试。
  • 即使我只使用该功能进行测试?另外,我不会同时测试这两个例程吗?
  • 如果您不想关注@casey,只需将其设置为公开以进行测试,然后再将其设置回私有!

标签: fortran


【解决方案1】:

在我看来,你有三种方法。

  1. 编写一个 get 函数来获取值并进行测试。您在 cmets 中指出这是次优的,所以..

  2. 如果您的编译器支持 Fortran 2003(例如任何最新版本的现代 Fortran 编译器),请使用 protected 属性而不是 private 属性声明变量。这将允许从任何代码中读取您的变量,但不会对其进行修改。这将强制它只能通过您的 setter 函数设置,但您可以直接在单元测试中检查它的值。

    integer, protected :: value
    
  3. 最后,如果所有其他方法都失败了,您可以有条件地编译模块,以便有时变量不是私有的。例如,这样做:

    module mod
      implicit none
      private
      integer :: value
      public :: set_value
    
    #ifdef UNITTESTING
      public :: value
    #endif
    
    contains
    ...
    end module
    

    然后将文件名从 .f90 更改为 .F90 以便对其进行预处理(至少在 gfortran 和 ifort 上)。当你正常编译它时,value 将是私有的,但如果你使用标志 -DUNITTESTING 编译,那么 value 将是公共的。当您编译测试用例时,您使用该标志,他们现在可以直接检查变量。

【讨论】:

  • 拜托,不是条件编译...替代方案可能受到保护,请参阅stackoverflow.com/questions/15020460/…
  • @IanBush 谢谢,我忘记了。我已经添加了这一点,但保留了条件编译部分作为备用,以防他们使用古老的编译器。
  • 太棒了!但是我不会删除评论,因为条件编译是邪恶的!!!!!! (坐下,等待 cmets)(但老实说,我认为这只是全局变量的一种更糟糕的形式)
  • 测试私有函数和子程序怎么样?我不同意@IanBush 关于 conticional 编译的观点,对我来说这是最不打扰的解决方案。我们中的一些人被 Fortran 90 困住了......
猜你喜欢
  • 2016-04-28
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多