จะสร้างและใช้ส่วนขยายประเภทอาร์เรย์ใน Fortran ได้อย่างไร [ทำซ้ำ]

ฉันมีคลาสฐานนามธรรม ฉันสร้างส่วนขยายของคลาสพื้นฐานสองอัน ฉันต้องการจัดเก็บอ็อบเจ็กต์ทั้งหมดที่สร้างจากคลาสขยายอันใดอันหนึ่งไว้ในอาร์เรย์เดียว ฉันเชื่อว่าฉันสามารถทำเช่นนี้ได้โดยการสร้างอาร์เรย์ของพอยน์เตอร์ที่ชี้ไปที่คลาสพื้นฐาน ฉันสามารถเติมอาร์เรย์ดังกล่าวด้วยส่วนขยายของคลาสฐานใดก็ได้ อย่างไรก็ตาม เมื่อฉันพยายามเรียกใช้โพรซีเดอร์ของออบเจ็กต์คลาสขยาย คอมไพลเลอร์จะบ่นว่าโพรซีเดอร์ไม่อยู่ในคลาสพื้นฐาน ฉันคิดว่าโค้ดจะรู้ว่าตัวชี้กำลังชี้ไปที่ส่วนขยาย และดูขั้นตอนผูกประเภทของมัน แต่ดูเหมือนว่าฉันผิด

ตัวอย่างแสดงไว้ด้านล่าง ฉันมีคำถามสองข้อ: ฉันจะต้องทำอย่างไรเพื่อแก้ไขปัญหานี้ และนี่เป็นวิธีที่ไม่ถูกต้องอย่างยิ่งในการแก้ไขปัญหาที่ฉันกำลังพยายามแก้ไขหรือไม่

module thetype

   implicit none

   type, abstract :: base
      integer :: ival
   end type base

   type, extends(base) :: extend1
      real :: val
      contains
         procedure :: Init=>Init_extend1
         procedure :: Print=>Print_extend1
   end type extend1

   type, extends(base) :: extend2
      character(len=1) :: chr
      contains
         procedure :: Init=>Init_extend2
         procedure :: Print=>Print_extend2
   end type extend2

   type :: ptr
      class(base), pointer :: ptrobj
   end type

contains

   subroutine Init_extend1(me,ival,val)
      class(extend1), intent(in out) :: me
      integer, intent(in) :: ival
      real, intent(in) :: val
      me%ival=ival
      me%val=val
   end subroutine Init_extend1

   subroutine Print_extend1(me,id)
      class(extend1), intent(in) :: me
      integer, intent(in) :: id
      print *, "Extend1 obj:", id
      print *, me%ival
      print *, me%val
   end subroutine Print_extend1

   subroutine Init_extend2(me,ival,chr)
      class(extend2), intent(in out) :: me
      integer, intent(in) :: ival
      character(len=1), intent(in) :: chr
      me%ival=ival
      me%chr=chr
   end subroutine Init_extend2

   subroutine Print_extend2(me,id)
      class(extend2), intent(in) :: me
      integer, intent(in) :: id
      print *, "Extend2 obj:", id
      print *, me%ival
      print *, me%chr
   end subroutine Print_extend2
end module thetype

program main
   use thetype
   implicit none

   type(extend1), target, allocatable :: extend1_obj(:)
   type(extend2), target, allocatable :: extend2_obj(:)
   type(ptr), allocatable :: ptrs(:)
   integer :: i

   allocate(extend1_obj(1))
   allocate(extend2_obj(2))
   allocate(ptrs(3))

   call extend1_obj(1)%Init(1,2.0)

   call extend2_obj(1)%Init(3,'a')
   call extend2_obj(2)%Init(3,'b')

   ptrs(1)%ptrobj=>extend1_obj(1)
   ptrs(2)%ptrobj=>extend2_obj(1)
   ptrs(3)%ptrobj=>extend2_obj(2)

   do i=1,size(ptrs,1)
      call ptrs(i)%ptrobj%Print(i)
   end do

end program main

person rks171    schedule 21.10.2015    source แหล่งที่มา
comment
คุณต้องประกาศขั้นตอนในคลาสฐาน (นี่คือสิ่งที่คอมไพเลอร์บอกคุณ) และคุณควรให้แอตทริบิวต์ deferred แก่พวกเขา ฉันไม่มีเวลาหรือปัญญาที่จะอธิบายให้ครบถ้วน แต่ pgroup.com/lit /articles/insider/v3n2a2.htm เป็นสถานที่ที่ดีในการเริ่มอ่านเกี่ยวกับเรื่องทั้งหมดนี้   -  person High Performance Mark    schedule 21.10.2015
comment
คำถามนี้ชัดเจนกว่าคำถามเดิมมาก   -  person Vladimir F    schedule 21.10.2015
comment
ใช่คุณถูก. ฉันเดาว่าคำถามของฉันมีลักษณะเชิงปรัชญามากกว่า ข้อกำหนดนี้บังคับให้ฉันต้องสร้างรายการอาร์กิวเมนต์ของโพรซีเดอร์ Init ทั้งหมดที่ขยายคลาสพื้นฐาน (ival,val,chr) อย่างไรก็ตาม 'extend1' ไม่ต้องการค่า chr และ 'extend2' ไม่ต้องการ 'val' นี่เป็นการบังคับให้ขั้นตอน Init ของฉันส่งผ่านข้อมูลที่ไม่จำเป็น ซึ่งดูเหมือนว่าจะผิด ฉันเดาว่าฉันไม่เห็นค่าของประเภทนามธรรมหากจำเป็นต้องประกาศขั้นตอนการขยายประเภททั้งหมดเป็นการเลื่อนออกไปในคลาสพื้นฐานและรายการอาร์กิวเมนต์ที่ตั้งไว้ มันฟังดูขยายความได้ไม่มากนัก   -  person rks171    schedule 23.10.2015
comment
@ HighPerformanceMark ฉันคิดว่าฉันเข้าใจคุณผิดในตอนแรก ฉันคิดว่าฉันต้องทำเครื่องหมายขั้นตอน 'เริ่มต้น' ที่ถูกเลื่อนออกไป ฉันผิดไป. ฉันต้องทำเครื่องหมาย 'พิมพ์' ว่าเลื่อนออกไปเนื่องจากฉันไม่มีโครงสร้าง 'เลือกประเภท' ใน do loop ดังนั้นอินเทอร์เฟซของขั้นตอน 'การพิมพ์' ทั้งหมดจะต้องเหมือนกัน ซึ่งสมเหตุสมผลอย่างยิ่ง ฉันสามารถทำให้โพรซีเดอร์ Init มีอินเทอร์เฟซใดก็ได้ที่ฉันต้องการ ตราบใดที่ฉันไม่พยายามเริ่มต้นส่วนขยายภายในลูปขนาดเดียวที่เหมาะกับทุกคน   -  person rks171    schedule 23.10.2015