Интерфейс оператора присваивания Fortran в производном типе данных

У меня есть следующий код:

    Module Hello
      Implicit None
    Type, Public :: TestOne
       Private
       Integer :: One, Two, Three
     contains
       Procedure, Pass, Public :: Set => SetSub
    End type TestOne
    Private :: SetSub
    Interface Assignment(=)
       Module Procedure SubgetValue
    End Interface Assignment(=)
    contains
      Subroutine SetSub(this)
        Implicit none
        Class(TestOne), Intent(InOut) :: this
        this%one=1
        this%two=2
        this%three=3
      End Subroutine SetSub
      Subroutine SubGetValue(ISOut,TSIn)
        Implicit None
        Integer, Intent(Out) :: ISOut
        Class(TestOne), Intent(In) :: TSIn
        ISOut=TSIn%one
      End Subroutine SubGetValue
    End Module Hello
    Program Test
      use Hello
      Implicit None
      Type(TestOne) :: TSTest
      Integer :: b
      call TSTest%Set()
      b=TSTest
      write(*,*) b
    End Program Test

В этой версии я могу получить доступ только к "TSTest%One" через "=". Вопрос в том, как я могу создать назначение интерфейса, чтобы я мог получить доступ к «TSTest%one», «TSTest%two» или «TSTest%three». Если бы «Один», «Два» и «Три» не были частными, это было бы тривиально. Однако цель состоит в том, чтобы сохранить их приватными и получить к ним доступ через назначение интерфейса. Любая дополнительная процедура модуля для доступа к "Two" или "Three" будет иметь те же фиктивные аргументы, что приведет к ошибке времени компиляции.

Тем не менее, другим способом решения этой проблемы может быть процедура "setter"/"getter", но я где-то читал в Интернете, что доступ к varialbe через присваивания намного быстрее, чем через процедуру "getter".

Какие-либо предложения.

Спасибо


person user1407220    schedule 02.10.2013    source источник


Ответы (1)


Ваша определенная процедура присваивания имеет те же накладные расходы, что и «геттер», потому что это то, что это такое.

Если (когда) межпроцедурная оптимизация компилятора находится на должном уровне, не должно быть никаких дополнительных накладных расходов, особенно в случае, когда объект TSTest не является полиморфным.

До редактирования...

Помимо любого очевидного единственного кандидата для извлечения с помощью присвоения смешанного типа, мой предпочтительный подход для этого состоит в том, чтобы иметь отдельные привязки для доступа к каждому компоненту.

TYPE, PUBLIC :: TestOne
  PRIVATE
  INTEGER :: One, Two, Three
CONTAINS
  PROCEDURE :: GetOne
  PROCEDURE :: GetTwo
  PROCEDURE :: GetThree
  ...

FUNCTION GetOne(this)
  CLASS(TestOne), INTENT(IN) :: this
  INTEGER :: GetOne
  GetOne = this%One
END FUNCTION GetOne
...

b = TSTTest%GetTwo()

Если я тогда чувствую себя творчески, я могу также добавить некоторые общие привязки типов для унарных операторов «доступа» к типу:

TYPE, PUBLIC :: TestOne
  PRIVATE
  INTEGER :: One, Two, Three
CONTAINS
  PROCEDURE :: GetOne
  ...
  GENERIC :: OPERATOR(.TheOneOutOf.) => GetOne
...

b = .TheOneOutOf. TSTTest

хотя иногда это творчество просто приводило к тому, что я слишком хорошо знакомился с каналами поддержки моего поставщика компилятора.

(Рассмотрите возможность привязки определенного типа присваивания.)

person IanH    schedule 02.10.2013