首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态选择对象类型

问动态选择对象类型
EN

Stack Overflow用户
提问于 2015-01-28 15:09:29
回答 1查看 85关注 0票数 1

我正在尝试为数值求解器制作灵活的用户界面。问题是,如何实现初值几何(矩形、球面等)的动态选择,是一个很难解决的问题。我尝试使用抽象类initial_conditions_geometry作为父类,其子类rectangular和sphere指定了某些属性,并为几何学实现了方法in_bounds:

代码语言:javascript
复制
type    ,abstract   ::  initial_conditions_geometry
    contains
        procedure (in_bounds)   ,deferred    :: in_bounds 
end type

abstract interface 
    logical function in_bounds(this,coordinates)
        import :: rkind
        import :: initial_conditions_geometry
        class(initial_conditions_geometry)  ,intent(in) :: this
        real(rkind)     ,dimension (:)      ,intent(in) :: coordinates
    end function in_bounds
end interface

type    ,extends(initial_conditions_geometry) :: rectangular
    integer ,dimension(:,:) ,allocatable    :: rectangular_bounds
contains
    procedure   :: in_bounds => in_bounds_rectangular
end type 

type    ,extends(initial_conditions_geometry) :: sphere
    integer ,dimension(:,:) ,allocatable    :: sphere_bounds
    integer ,dimension(:)   ,allocatable    :: sphere_center
contains
    procedure   :: in_bounds => in_bounds_sphere
end type

interface rectangular
    procedure constructor_rectangular
end interface

interface sphere
    procedure constructor_sphere
end interface

下面是initial_conditions_layer类定义,它包含初始条件几何和分布:

代码语言:javascript
复制
type    :: initial_conditions_layer
    class(initial_conditions_geometry)  ,allocatable    :: layer_geometry
    type(initial_conditions_distribution)               :: distributor
end type   

interface initial_conditions_layer
    procedure   constructor
end interface

问题是:如何为initial_conditions_layer动态创建构造器(取决于某些文本文件中的几何类型)设置layer_geometry类型(矩形、球形等)?

编辑,也许添加一些解决这个问题的尝试是有用的。我尝试按照以下方式组织initial_conditions_layer对象的构造函数:

代码语言:javascript
复制
type(initial_conditions_layer) function constructor(dimensions,layer_number,initial_conditions_data_file_unit)
    integer ,intent(in) :: layer_number
    integer ,intent(in) :: initial_conditions_data_file_unit
    integer ,intent(in) :: dimensions
    character(len=20)   :: layer_distribution_type
    character(len=20)   :: layer_geometry_name     

    call get_layer_properties(initial_conditions_data_file_unit,layer_number,layer_geometry_name,layer_distribution_type)

    select case(layer_geometry_name)
    case('rectangular')
        allocate(rectangular::constructor%layer_geometry)
    case('sphere')
        allocate(sphere::constructor%layer_geometry)
    end select

    select type(constructor%layer_geometry)
    type is(rectangular)
        constructor%layer_geometry = rectangular()
    type is(sphere)
        constructor%layer_geometry = sphere()
    end select
end function

但这需要在select类型构造中使用associate_name。Associate_name应该是指向initial_conditions_geometry的指针,但不能将目标属性设置为派生类型字段。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-28 18:55:43

你所拥有的与工作相当接近,我认为你只是有一个误会。

但这需要在select类型构造中使用associate_name。Associate_name应该是指向initial_conditions_geometry的指针,但不能将目标属性设置为派生类型字段。

在这种情况下需要一个associate-name,但是,不管=>语法如何,都不涉及指针。这样你就可以在没有其他变化的情况下

代码语言:javascript
复制
select type(clg => constructor%layer_geometry)
type is(rectangular)
    clg = rectangular()
type is(sphere)
    clg = sphere()
end select

或者,在这种简单的情况下,可以完全取消select type构造,并处理您已经拥有的select case中的内容。

在每个构造函数中使用源分配:

代码语言:javascript
复制
select case(layer_geometry_name)
case('rectangular')
    allocate(constructor%layer_geometry, source=rectangular())
case('sphere')
    allocate(constructor%layer_geometry, source=sphere())
end select

甚至

代码语言:javascript
复制
select case(layer_geometry_name)
case('rectangular')
    constructor%layer_geometry = rectangular()
case('sphere')
    constructor%layer_geometry = sphere()
end select

如果编译器支持对多态变量的内部赋值(或通过使用定义的赋值)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28195626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档