首页 > 解决方案 > 通用接口和运算符重载 - 如何将通用接口块中的过程设置为模块中的私有?

问题描述

我的 IDE 是: Code::Blocks 20.03 ( MinGW 9.2.0 )

这是我的代码:

module mod_kompleks

  use, intrinsic :: iso_c_binding, only : rp => c_double

  implicit none

  type, public :: kom_bro

    real(rp), private :: rea
    real(rp), private :: img

    contains

      procedure, pass(kdt), private :: kom_bro_ini
      procedure, pass(kdt),  public :: uzm_rea => uzm_pod_rea
      procedure, pass(kdt),  public :: uzm_img => uzm_pod_img
      procedure, pass(kdt), private :: kom_bro_sab

      generic, public :: operator(+) => kom_bro_sab

  end type kom_bro

  interface kom_bro

    module procedure kom_bro_kon

  end interface kom_bro

  private :: kom_bro_kon

contains

  function kom_bro_kon( bro_rea, bro_img ) result( bro )

    real(rp), intent(in) :: bro_rea
    real(rp), intent(in) :: bro_img
    type(kom_bro)        :: bro

    call bro%kom_bro_ini(bro_rea, bro_img)

  end function kom_bro_kon

  subroutine kom_bro_ini(kdt, dio_rea, dio_img)

    class(kom_bro), intent(out) :: kdt
     real(rp),      intent(in)  :: dio_rea
     real(rp),      intent(in)  :: dio_img

     kdt%rea = dio_rea
     kdt%img = dio_img

  end subroutine kom_bro_ini

  function uzm_pod_rea( kdt ) result( rez )

    class(kom_bro), intent(in) :: kdt
     real(rp)                  :: rez

     rez = kdt%rea

  end function uzm_pod_rea

  function uzm_pod_img( kdt ) result( rez )

    class(kom_bro), intent(in) :: kdt
     real(rp)                  :: rez

     rez = kdt%img

  end function uzm_pod_img

  function kom_bro_sab( kdt, bro ) result( rez )

    class(kom_bro), intent(in) :: kdt
    class(kom_bro), intent(in) :: bro
     type(kom_bro)             :: rez

     rez%rea = kdt%rea + bro%rea
     rez%img = kdt%img + bro%img

  end function kom_bro_sab

end module mod_kompleks

program kompleksni_broj

  use, non_intrinsic :: mod_kompleks

  implicit none

  type(kom_bro) :: broj_01, broj_02, broj_03

  broj_01 = kom_bro(1.1_rp,2.2_rp)

  print '(1x,f4.2,1x,"j",1xf4.2)', broj_01%uzm_rea(), broj_01%uzm_img()

  broj_02 = kom_bro(3.3_rp,4.4_rp)

  print '(1x,f4.2,1x,"j",1xf4.2)', broj_02%uzm_rea(), broj_02%uzm_img()

  broj_03 = broj_01 + broj_02

  print '(1x,f4.2,1x,"j",1xf4.2)', broj_03%uzm_rea(), broj_03%uzm_img()

end program kompleksni_broj

我的意图是禁用对模块kom_bro_sab外部过程的访问。mod_kompleks如果我想在主程序中构造一个具有实部和虚部值的复数,在输入单词 kom 后,我有机会选择过程kon_bro,这当然是我想要的,但在该功能旁边我提供有机会选择程序kom_bro_sab。我怎样才能防止这种情况(我只希望程序kom_bro_sab和操作员+可见)?我将添加我得到的截图,即使类型绑定程序是私有的: kom_bro_sab

标签: fortrangfortran

解决方案


简而言之

kom_bro_sab函数具有(默认)访问属性public,这就是您可以kom_bro_sab在主程序中访问的原因。

解释

该函数kom_bro_sab被导出为任何其他函数,因为它的访问属性是public. 这是因为默认情况下,访问属性public在此处已更改且未更改。

不要被线路所迷惑procedure, pass(kdt), private :: kom_bro_sab。这里定义了一个类型绑定过程kom_bro_sab,它具有访问属性private。因此,您只能从其他类型绑定过程调用此属性。您应该区分类型绑定过程和函数本身。

解决方案

有两种方法可以处理它。

  1. 将默认访问属性更改为private仅显式定义public实体。这也使得在快速浏览模块以查看实际导出的实体时更容易。
module mod_kompleks
  use, intrinsic :: iso_c_binding, only : rp => c_double
  implicit none
  private
  public kom_bro
  
  type kom_bro
...
end module
  1. public您可以通过显式定义和private属性来保持您正在做的事情。然后你只需要添加一行(参见包含 的行ADDED)。
module mod_kompleks
  use, intrinsic :: iso_c_binding, only : rp => c_double
  implicit none
  type, public :: kom_bro
...
  end interface kom_bro
  private kom_bro_kon
  private kom_bro_sab     ! <- ADDED
...
end module

我缩短了您的代码,希望它仍然可以理解。


推荐阅读