Fortran中如何避免对同类型多class对象重复执行select type检查?
解决Fortran多态对象类型检查的简化方案
针对你提出的问题——仅通过检查一个继承自base的多态对象,就能访问另一个同类型对象的扩展成员,以下是两种可行的解决办法:
方法1:在select type块内关联并转换第二个对象
利用Fortran的类型转换和associate构造,在已完成类型检查的select type分支中,将第二个对象转换为对应的扩展类型(因已知二者类型相同,转换安全),从而直接访问其成员:
type :: base end type base type, extends(base) :: typeA integer :: i end type typeA type, extends(base) :: typeB integer :: j end type typeB subroutine process(obj1, obj2) class(base), intent(inout) :: obj1, obj2 select type(obj1) type is (typeA) associate(obj2_a => type(typeA) :: obj2) obj1%i = obj1%i + obj2_a%i end associate type is (typeB) associate(obj2_b => type(typeB) :: obj2) obj1%j = obj1%j + obj2_b%j end associate end select end subroutine process
方法2:使用多对象select type(推荐)
Fortran 2008及以后标准支持在select type语句中同时指定多个多态对象,编译器会自动验证它们的类型一致性,只需一次检查即可同时绑定所有对象到目标扩展类型,写法更简洁:
subroutine process(obj1, obj2) class(base), intent(inout) :: obj1, obj2 select type(obj1 => obj1, obj2 => obj2) type is (typeA) obj1%i = obj1%i + obj2%i type is (typeB) obj1%j = obj1%j + obj2%j ! 若需处理类型不匹配的异常,可添加class default分支 ! class default ! error stop "Objects are not of the same type" end select end subroutine process
关键说明
- 两种方法都基于“两个对象类型相同”的前提,若存在类型不匹配的可能,建议添加
class default分支处理异常,避免运行时错误。 - 方法2需要编译器支持Fortran 2008标准,主流编译器(GCC、Intel Fortran)均已兼容。
内容的提问来源于stack exchange,提问作者fdv
相关产品推荐
相关产品推荐

