抽象 class 初始化私有变量的 Fortran 构造函数
Fortran constructor of abstract class initializing private variables
我从 Fortran 开始,我想尝试一个非常简单的例子——一个抽象的 class Connection,然后是它派生的 class IntervalConnection,而 Connection class 会有一个已定义构造函数,IntervalConnection 将继承此构造函数。
在这个构造函数中,我有几个需要初始化的私有变量。
问题是,我在尝试创建新对象时遇到以下错误:
连接.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()
。这些是不同的!
您可能误解了构造函数如何处理参数和 return 值。任何 this
参数都没有位置。构造函数不是类型绑定过程。它不是继承的。但如果需要,子连接可以调用父构造函数。有时你想要那个,有时不需要。请注意 returned 值是 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 创建构造函数的实例,而不是像您尝试的那样为 Connection 创建实例
interface IntervalConnection
module procedure new_interval_connection
end interface Connection
con = IntervalConnection(n1, n2, 5.0)
我从 Fortran 开始,我想尝试一个非常简单的例子——一个抽象的 class Connection,然后是它派生的 class IntervalConnection,而 Connection class 会有一个已定义构造函数,IntervalConnection 将继承此构造函数。
在这个构造函数中,我有几个需要初始化的私有变量。
问题是,我在尝试创建新对象时遇到以下错误: 连接.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()
。这些是不同的!
您可能误解了构造函数如何处理参数和 return 值。任何 this
参数都没有位置。构造函数不是类型绑定过程。它不是继承的。但如果需要,子连接可以调用父构造函数。有时你想要那个,有时不需要。请注意 returned 值是 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 创建构造函数的实例,而不是像您尝试的那样为 Connection 创建实例
interface IntervalConnection
module procedure new_interval_connection
end interface Connection
con = IntervalConnection(n1, n2, 5.0)