我正在尝试设计一个由对象组成的数据结构,这些对象包含另一种类型的对象作为实例变量。
我希望能够做这样的事情:
CALL type1_object%get_nested_type2_object()%some_type2_method()
请注意,我正在尝试立即使用getter get_nested_type2_object()
,然后根据其返回值调用返回的type2对象中的方法。
目前,gfortran v4.8.2不接受这种语法,并认为get_nested_type2_object()
是一个数组引用,而不是函数调用。有没有什么语法可以用来澄清这一点,或者标准不允许这样做?
为了给出一个更具体的例子,这里有一些代码来说明这一点:
家具_类别.F95:
MODULE furniture_class
IMPLICIT NONE
TYPE furniture_object
INTEGER :: length
INTEGER :: width
INTEGER :: height
CONTAINS
PROCEDURE :: get_length
END TYPE furniture_object
CONTAINS
FUNCTION get_length(self)
IMPLICIT NONE
CLASS(furniture_object) :: self
INTEGER :: get_length
get_length = self%length
END FUNCTION
END MODULE furniture_class
现在,房间对象可能包含一个或多个家具对象。
房间类别.F95:
MODULE room_class
USE furniture_class
IMPLICIT NONE
TYPE :: room_object
CLASS(furniture_object), POINTER :: furniture
CONTAINS
PROCEDURE :: get_furniture
END TYPE room_object
CONTAINS
FUNCTION get_furniture(self)
USE furniture_class
IMPLICIT NONE
CLASS(room_object) :: self
CLASS(furniture_object), POINTER :: get_furniture
get_furniture => self%furniture
END FUNCTION get_furniture
END MODULE room_class
最后,这里有一个程序,我试图访问房间内的家具对象(但编译器不允许):
房间测试F95
PROGRAM room_test
USE room_class
USE furniture_class
IMPLICIT NONE
CLASS(room_object), POINTER :: room_pointer
CLASS(furniture_object), POINTER :: furniture_pointer
ALLOCATE(room_pointer)
ALLOCATE(furniture_pointer)
room_pointer%furniture => furniture_pointer
furniture_pointer%length = 10
! WRITE(*,*) 'The length of furniture in the room is', room_pointer%furniture%get_length() - This works.
WRITE(*,*) 'The length of furniture in the room is', room_pointer%get_furniture()%get_length() ! This line fails to compile
END PROGRAM room_test
如果我不使用getter返回嵌套对象,我当然可以直接访问家具对象,但这会破坏封装,并可能在生产代码中出现问题,而生产代码比我在这里展示的要复杂得多。
我想要做的是Fortran标准不支持,还是只需要一个更兼容的编译器?
标准语言的语法不支持您想要做的事情。
(可能适用于"取消引用"函数结果的一般语法(不一定是这种特定情况)的变体可能是不明确的——考虑子字符串、整个数组引用、数组节等。)
通常,您将第一个函数调用的结果分配给适当类型的[pointer]变量,然后将第二个函数的绑定应用于该变量。
或者,如果要将运算应用于表达式中的主函数(如函数引用)以提供另一个值,则可以使用运算符。
一些可能相当主观的评论:
-
房间对象实际上并不包含家具对象,而是包含对家具对象的引用。也许您使用该引用的方式暗示了"包含"它的父对象,但这不是组件定义自然建议的。
(使用指针组件表明您希望房间指向(即参考)某些家具。就语言而言,指针组件引用的对象通常不被视为组件父对象值的一部分-考虑内部赋值的工作方式、修改INTENT(In)参数的限制等。
一个非指针组件向我表明家具是房间的一部分。在Fortran语言的意义上,对象是一个非指针组件,它始终是组件父对象值的一部分。
突出显示不同房间中的指针组件可能指向同一件家具;无指针家具对象只能直接作为一个房间的一部分。)
-
使用带有指针结果的函数时需要非常小心。在一般情况下,是不是:
p = some_ptr_function(args)
(也许我不小心泄露了内存)或
p => some_ptr_function(args)
只有一点字符差异,两种语法都有效,语义完全不同。如果第二种情况是预期的,那么为什么不通过子例程参数将指针传回来呢?打字上的一个无关紧要的区别,它更安全。
一个适用于上述某些情况的一般提醒——在表达式的上下文中,对函数引用的求值会产生一个值。值不是变量,因此不允许更改[修改]它们。