Bagaimana cara membuat dan menggunakan array tipe ekstensi di Fortran? [duplikat]

Saya memiliki kelas dasar abstrak. Saya membuat dua ekstensi dari kelas dasar. Saya ingin menyimpan semua objek yang dibuat dari salah satu kelas yang diperluas dalam satu array. Saya yakin saya dapat melakukan ini dengan membuat array pointer yang menunjuk ke kelas dasar; Saya dapat mengisi array seperti itu dengan ekstensi apa pun dari kelas dasar. Namun, ketika saya mencoba memanggil prosedur dari objek kelas yang diperluas, kompiler mengeluh bahwa prosedur tersebut tidak ada di kelas dasar. Saya pikir kode akan mengetahui bahwa penunjuk menunjuk ke ekstensi, dan melihat prosedur terikat tipenya, tetapi ternyata saya salah.

Contohnya ditunjukkan di bawah ini. Saya punya dua pertanyaan: Apa yang harus saya lakukan untuk memperbaikinya, dan apakah ini cara yang salah dalam mendekati masalah yang ingin saya selesaikan?

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 sumber
comment
Anda perlu mendeklarasikan prosedur di kelas dasar (inilah yang dikatakan oleh kompiler) dan Anda harus memberinya atribut deferred. Saya tidak punya waktu atau akal untuk menjelaskan sepenuhnya tetapi pgroup.com/lit /articles/insider/v3n2a2.htm adalah tempat yang baik untuk mulai membaca tentang semua ini.   -  person High Performance Mark    schedule 21.10.2015
comment
Pertanyaan ini jauh lebih jelas daripada duplikat aslinya.   -  person Vladimir F    schedule 21.10.2015
comment
Ya kamu benar. Saya kira pertanyaan saya lebih bersifat filosofis. Persyaratan ini memaksa saya untuk membuat daftar argumen dari semua prosedur Init yang memperluas kelas dasar (ival,val,chr). Namun, 'extend1' tidak memerlukan nilai chr dan 'extend2' tidak memerlukan 'val'. Ini memaksa prosedur Init saya untuk meneruskan data yang tidak diperlukan, yang sepertinya salah. Saya kira saya gagal melihat nilai tipe abstrak jika semua prosedur ekstensi tipe perlu dideklarasikan sebagai ditangguhkan di kelas dasar dan daftar argumen ditetapkan. Kedengarannya tidak bisa diperluas.   -  person rks171    schedule 23.10.2015
comment
@HighPerformanceMark, saya rasa saya salah memahami Anda pada awalnya. Saya pikir saya harus menandai prosedur 'Init' ditangguhkan. Saya salah. Saya harus menandai 'Cetak' sebagai ditangguhkan karena saya tidak memiliki konstruksi 'tipe pilihan' di loop do. Oleh karena itu, antarmuka semua prosedur 'Cetak' harus sama, dan ini sangat masuk akal. Saya dapat membuat prosedur Init memiliki antarmuka apa pun yang saya inginkan selama saya tidak mencoba menginisialisasi ekstensi di dalam loop satu ukuran untuk semua.   -  person rks171    schedule 23.10.2015