Fortran派生类型重载类型名后自定义构造函数未被调用问题
问题根因
你编写的自定义构造函数没有被编译器正确匹配,程序触发了默认派生类型结构构造函数的校验规则,才抛出参数缺失错误。匹配失败的核心原因:
你定义的make_foo函数中,str哑元为固定长度character(512),调用时传入的字符串字面量"hello"长度仅为5,Fortran泛型接口的匹配规则要求固定长度字符类型哑元必须和实参长度严格一致,因此编译器无法匹配到你写的自定义构造函数,退而使用默认结构构造函数。而默认构造函数要求所有派生类型组件必须显式赋值,所以会报flag1未初始化的错误。
修复方案
只需要把自定义构造函数中str的参数类型改为假定长度字符型character(len=*),即可兼容任意长度的输入字符串,让编译器正确匹配到自定义构造函数,符合你的需求。
修复后的完整可运行代码如下:
module test implicit none type, public :: foo character(512) :: str logical :: flag1 logical :: flag2 end type ! 重载foo类型构造接口 interface foo module procedure make_foo end interface contains ! 自定义构造函数 function make_foo(str, flag1) result(self) implicit none type(foo) :: self ! 修改为假定长度字符型,兼容任意长度输入 character(len=*), intent(in) :: str logical, intent(in), optional :: flag1 self % str = str self % flag1 = .false. if (present(flag1)) self % flag1 = flag1 self % flag2 = .false. end function end module program tmp use test implicit none type(foo) :: a a = foo("hello") ! 可选参数调用示例:a = foo("hello", flag1=.true.) end program
补充说明
如果需要彻底避免默认构造函数被误触发,可以将派生类型的组件设置为private,同时对外提供组件的访问接口,此时编译器不会生成公共的默认构造函数,所有构造操作都会走你自定义的实现。
该代码在gfortran 10.2.0版本下可正常编译运行,完全满足你的要求:
- 必须传入
str参数 flag1为可选传入参数,默认值为.false.flag2完全由构造函数内部赋值,无需外部传入
内容的提问来源于stack exchange,提问作者Sine
相关产品推荐
相关产品推荐

