Tôi là người mới bắt đầu trong OOP với Fortran và tôi đang cố viết một chương trình với các thủ tục xử lý các biến đa hình làm đối số. Mặc dù mã ban đầu của tôi phức tạp hơn nhiều (nhiều thủ tục, một số kiểu có nguồn gốc ...), tôi có thể cô lập một ví dụ đơn giản về vấn đề của tôi, nói: Tôi có một thủ tục sao chép một biến đa hình và hơi sửa đổi bản sao này.Đa hình Fortran, chức năng và phân bổ
tôi đã có thể viết thành công chương trình thử nghiệm của tôi bằng cách sử dụng chương trình con :
MODULE my_module
type :: my_type
real :: data
endtype my_type
type, extends(my_type) :: my_derived_type
end type my_derived_type
CONTAINS
subroutine sub_copy(old,new)
implicit none
class(my_type), intent(in) :: old
class(my_type), allocatable, intent(out) :: new
allocate(new, source = old)
new%data = new%data + 1
end subroutine sub_copy
END MODULE my_module
PROGRAM my_prog
use my_module
implicit none
type(my_derived_type) :: x
class(my_type), allocatable :: y
x%data = 1.0
call sub_copy(x,y)
print*,y%data
deallocate(y)
END PROGRAM my_prog
này thực hiện độc đáo cả về kết quả mong đợi và việc phân bổ bộ nhớ/deallocation.
Tuy nhiên, tôi đã đấu tranh cho những ngày cố gắng làm việc chức năng Fortran sẽ thực hiện cùng một công việc.
Dường như một chức năng được xác định theo một cách tương tự như các chương trình con (xem ở đây sau) không thể được sử dụng đơn giản là
y = fun_copy(x)
và trình biên dịch gfortran tôi (v5.0.0) than phiền:
Error: Assignment to an allocatable polymorphic variable at (1) is not yet supported
Tôi đã đọc ở đây và ở đó thực sự chuyển nhượng như vậy không được hỗ trợ bởi trình biên dịch của tôi. Chờ đợi cho điều đó, tôi đã cố gắng để làm việc đó xung quanh bằng cách xác định toán tử gán của riêng tôi (=). Các mã sau đây hoạt động:
MODULE my_module
type :: my_type
real :: data
endtype my_type
type, extends(my_type) :: my_derived_type
end type my_derived_type
interface assignment(=)
module procedure myassign
end interface
CONTAINS
function fun_copy(old) result(new)
implicit none
class(my_type), intent(in) :: old
class(my_type), allocatable :: new
allocate(new, source = old)
new%data = new%data + 1
end function fun_copy
subroutine myassign(new,old)
class(my_type), intent(in) :: old
class(my_type), allocatable, intent(out) :: new
allocate(new, source=old)
end subroutine
END MODULE my_module
PROGRAM my_prog
use my_module
implicit none
type(my_derived_type) :: x
class(my_type), allocatable :: y
x%data = 1.0
y = fun_copy(x)
print*,y%data
deallocate(y)
END PROGRAM my_prog
Nó hoạt động theo nghĩa là trên thực tế, một bản sao của x
được tạo ra như y
. Tuy nhiên, kiểm tra ngân sách bộ nhớ của chương trình thử nghiệm đơn giản này (tôi sử dụng phần mềm Instrument trên OS X), có vẻ như một số bộ nhớ không được phân phối trước khi kết thúc. Tôi nghi ngờ rằng chức năng sao chép và phân bổ chương trình con cả cấp phát bộ nhớ và tôi chỉ miễn phí một lần xuất hiện, để lại một lần được phân bổ.
Vì tôi dự định sử dụng một số lần thường xuyên như vậy trong một mã phức tạp hơn nhiều, tôi thực sự lo ngại về phân bổ bộ nhớ/deallocation. Tất nhiên, tôi có thể sử dụng phiên bản chương trình chương trình con của chương trình, nhưng nếu có cách nào, tôi thích phiên bản chức năng.
Có cách nào để giải quyết vấn đề như vậy không?
Trong ví dụ chức năng của bạn, bạn có nghĩa là 'y = fun_copy (x)', tôi đoán vậy. Như một cách giải quyết khác 'cấp phát (y, source = fun_copy (x))', nhưng điều này không hấp dẫn. Nó sẽ là thú vị để xem liệu điều tương tự vẫn tồn tại, mặc dù. – francescalus
@francescalus Vâng, tôi có nghĩa là 'y = fun_copy (x)'. Tôi đã chỉnh sửa bài đăng gốc và sửa lại. Ngoài ra, tôi vừa thử cách giải quyết của bạn và vấn đề phân bổ bộ nhớ/deallocation vẫn tồn tại. Không có thay đổi nào xa như tôi có thể nói. – Reno
Vâng, tôi không (chưa?) Biết câu trả lời, nhưng tôi cho rằng chúng ta có thể loại trừ sự phân công được xác định là vấn đề. – francescalus