constructor - 抽象类的 Fortran 构造函数初始化私有(private)变量

标签 constructor fortran abstract-class fortran2008

我从 Fortran 开始,我想尝试一个非常简单的示例 - 一个抽象类 Connection,然后是它的派生类 IntervalConnection,而 Connection 类将定义一个构造函数,并且 IntervalConnection 将继承此构造函数。

在这个构造函数中,我有几个私有(private)变量,我需要初始化它们。

问题是,在尝试创建新对象时出现以下错误: 连接.f08:152:10:

    con = IntervalConnection(n1_p, n2_p, 5.0)
          1
Error: Component ‘input_neuron’ at (1) is a PRIVATE component of ‘connection’

我想我没有正确定义构造函数new_connection。请您告诉我,我应该如何更好地实现它?


我的代码

module Connection_mod
    implicit none

    public

    ! TODO smazat
    type :: Neuron
        real, private :: state

        contains
            procedure :: get_state => get_state_impl
            procedure :: set_state => set_state_impl
    end type Neuron

    !------------------!------------------------------------------------------------------------
    ! Type definitions !
    !------------------!
    type, abstract :: Connection
        class(Neuron), pointer, private :: input_neuron
        class(Neuron), pointer, private :: output_neuron
        real, private                   :: weight

        contains

            procedure :: adjust_weight     => adjust_weight_impl

            ! Getters and setters    
            procedure :: get_input_neuron  => get_input_neuron_impl
            procedure :: get_output_neuron => get_output_neuron_impl
            procedure :: get_weight        => get_weight_impl

    end type Connection

    type, extends(Connection) :: IntervalConnection
       contains
          procedure :: pass_signal => pass_signal_impl
    end type IntervalConnection

    !------------!------------------------------------------------------------------------------
    ! Interfaces !
    !------------!
    interface Connection
        module procedure new_connection
    end interface Connection

    contains
    !------------------------!------------------------------------------------------------------
    ! Method implementations !
    ! -----------------------!

        !--------------!
        ! class Neuron !
        !--------------!
        ! TODO smazat
        function get_state_impl(this) result(state)
            class(Neuron), intent(in) :: this
            real                      :: state

            state = this%state
        end function get_state_impl

        ! TODO smazat
        function set_state_impl(this, new_state) result(ret_this)
            class(Neuron), target  :: this
            real, intent(in)       :: new_state
            class(Neuron), pointer :: ret_this

            ret_this   => this
            this%state = new_state
        end function set_state_impl

        !------------------!
        ! class Connection !
        !------------------!
        subroutine adjust_weight_impl(this, added_value)
            class(Connection), intent(inout) :: this
            real, intent(in)                 :: added_value

            this%weight = this%weight + added_value
        end subroutine adjust_weight_impl

        !--------------------------!
        ! class IntervalConnection !
        !--------------------------!
        subroutine pass_signal_impl(this)
            ! TODO dokoncit
            class(IntervalConnection), intent(in) :: this
            real :: a
            class(Neuron), pointer :: dummy

            a=this%weight * this%input_neuron%get_state()

            dummy => this%output_neuron%set_state(5.0)

            !this%output_neuron%set_state(this%weight * this%input_neuron%get_state())
        end subroutine pass_signal_impl

        !--------------!------------------------------------------------------------------------
        ! Constructors !
        !--------------!
        function new_connection(this, input_neuron, output_neuron, weight) result(ret_this)
            class(Connection), target  :: this
            class(Connection), pointer :: ret_this
            class(Neuron), pointer     :: input_neuron
            class(Neuron), pointer     :: output_neuron
            real, intent(in)           :: weight

            ret_this           => this
            this%input_neuron  => input_neuron
            this%output_neuron => output_neuron
            this%weight        = weight
        end function new_connection

        !-------------------!-------------------------------------------------------------------
        ! Getters & Setters !
        !-------------------!
        function get_input_neuron_impl(this) result (input_neuron)
            class(Connection), target, intent(in) :: this
            class(Neuron), pointer                :: input_neuron

            input_neuron => this%input_neuron
        end function get_input_neuron_impl

        function get_output_neuron_impl(this) result (output_neuron)
            class(Connection), target, intent(in) :: this
            class(Neuron), pointer                :: output_neuron

            output_neuron => this%output_neuron
        end function get_output_neuron_impl

        function get_weight_impl(this) result (weight)
            class(Connection), intent(in) :: this
            real                          :: weight

            weight = this%weight
        end function get_weight_impl
end module Connection_mod

program a
    use Connection_mod

    type(Neuron), target :: n1
    type(Neuron), target :: n2

    type(Neuron), pointer :: n1_p
    type(Neuron), pointer :: n2_p

    type(IntervalConnection) :: con

    n1_p => n1
    n2_p => n2
    con = IntervalConnection(n1_p, n2_p, 5.0)

end program a

最佳答案

您作为构造函数创建的函数需要四个参数

function new_connection(this, input_neuron, output_neuron, weight)

但你用三个参数调用它

class(IntervalConnection) :: con

con = IntervalConnection(n1_p, n2_p, 5.0)

我把作业移走了。这并不是绝对必要的。


因此通用解析(TKR)无法成功,将尝试默认构造函数。

并且您还重载了构造函数或Connection,但随后调用了IntervalConection()。这些是不同的!

您可能误解了构造函数如何处理参数和返回值。没有任何地方可以容纳任何 this 参数。构造函数不是类型绑定(bind)过程。它不是遗传的。但如果需要,子连接可以调用父构造函数。有时你想要那样,有时则不然。请注意,返回值是 type,而不是 class!

function new_interval_connection(input_neuron, output_neuron, weight) result(ret)
        type(IntervalConnection) :: ret
        class(Neuron), pointer     :: input_neuron
        class(Neuron), pointer     :: output_neuron
        real, intent(in)           :: weight

        ret%input_neuron  => input_neuron
        ret%output_neuron => output_neuron
        ret%weight        = weight
end function new_interval_connection

您想要为 IntervalConnection 创建一个 make 构造函数的实例,而不是像您尝试的那样为 Connection 创建构造函数

interface IntervalConnection
    module procedure new_interval_connection
end interface Connection

con = IntervalConnection(n1, n2, 5.0)

关于constructor - 抽象类的 Fortran 构造函数初始化私有(private)变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47360481/

相关文章:

dart - 构造函数:将预处理的参数存储在传递给最终字段的辅助变量中

java - 尽管显式编写了另一个构造函数,但是否创建了空构造函数?

java - 使用 JButton ActionListener 在同一个包中运行不同的类

algorithm - 生成和求和素数

java - <anonymous> 不是抽象的,不会覆盖 AsyncHttpResponseHandler 中的抽象方法 onFailure(int,Header[],byte[],Throwable)

c++ - 深度复制 c++ - 如果给出指向该类的指针,则复制该类

带有模块和外部库的 Fortran 程序的 cmake

字符串的 C 和 Fortran 互操作性

python - 在 PyCharm 中不强制从具有具体类型参数的泛型抽象类继承

c++ - 子类中的纯虚声明