代码之家  ›  专栏  ›  技术社区  ›  veryreverie

Fortran 2008中带有非多态过程的重载延迟过程

  •  2
  • veryreverie  · 技术社区  · 7 年前

    是否可以用非多态过程重载延迟过程?

    我想创建一个抽象类( Parent )使用程序( foo )每个扩展的类都必须重载 父母亲 .当我想再次扩展时遇到问题,例如( Grandchild )扩展类( Child )它扩展了 父母亲

    由于Child不是抽象的,它的foo( foo_Child )必须是多态的。但是后来 孙子 继承 foo\u儿童 ,而不是被迫定义 foo_Grandchild .更进一步,因为我不想 foo\u儿童 要实现多态性,我希望能够使用 小孩 -特定的非多态功能 foo\u儿童

    module test_module
    
      type, abstract :: Parent
      contains
        procedure(foo_Parent), deferred :: foo
      end type
    
      abstract interface
        subroutine foo_Parent(this,input)
          import Parent
          class(Parent), intent(out) :: this
          character(*),  intent(in)  :: input
        end subroutine
      end interface
    
      type, extends(Parent) :: Child
      contains
        procedure :: foo => foo_Child
      end type
    
      type, extends(Child) :: Grandchild
        ! Is not required to define foo=>foo_Grandchild.
        ! This is not the behaviour I want.
      end type
    
      interface Child
        module procedure new_Child
      end interface
    contains
    
    function new_Child(input) result(this)
      character(*), intent(in) :: input
      type(Child)              :: this
    end function
    
    subroutine foo_Child(this,input)
      type(Child),  intent(out) :: this ! Fails: 'this' is not polymorphic.
      character(*), intent(in)  :: input
    
      this = Child(input) ! Fails if type(Child) is replaced by class(Child).
    end subroutine
    end module
    
    program test
      use test_module
    end program
    

    总结如下:

    有没有办法 foo\u儿童 非多态但也过载 foo_Parent ? 或者有没有一种方法可以调用非多态函数(至少 Child=Child 多态程序中非多态rhs的赋值?如果没有,是否有解决方法?

    (我不想定义 class(Child)=type(Child) ,但如果这是唯一的选择,则会)。

    1 回复  |  直到 7 年前
        1
  •  3
  •   IanH    7 年前

    与过程绑定的传递对象相对应的伪参数必须始终是多态的。

    内在赋值语言的规则不允许对不可分配的多态对象进行赋值。这是因为这样的赋值通常是一个类似于切片的错误-您将取消定义在rhs的动态类型中声明的对象位,而不是在lhs的声明类型中声明的对象位。

    使用选择类型和匹配对象动态类型的类型保护,可以将多态对象向下转换为非多态对象。您还可以通过参数关联愉快地切分到您心中的内容-多态的实际参数可以与相同声明类型的非多态伪参数相关联。

    可以通过使父类型抽象并使绑定延迟(或保留)来强制扩展实现绑定(正如您已经做的那样)。在您的情况下,可能需要在层次结构中添加其他类型。

    Parent (abstract) --> Child (abstract) +-> RealChild (concrete)
                                           |-> GrandChild (concrete)
    

    Child 在上面的例子中,可能只是让foo绑定延迟,或者它可能为该绑定提供一个过程,然后引入一个新的延迟绑定 RealChild GrandChild 需要实施。

    推荐文章