Is it currently possible to override the structure constructor in Fortran?
No. Quoi qu'il en soit même en utilisant votre approche n'est pas complètement sur le constructeur surchargé. La raison principale est ce constructeur de structure # OOP constructeur. Il y a une certaine similitude mais c'est juste une autre idée.
Vous ne pouvez pas utiliser votre fonction non intrinsèque dans l'expression d'initialisation. Vous pouvez utiliser uniquement un constructeur de constante, de tableau ou de structure, des fonctions intrinsèques, ... Pour plus d'informations, jetez un oeil à 7.1.7 Expression d'initialisation dans le brouillon de Fortran 2003.
Prenant compte de ce fait, je complètement ne comprends pas quelle est la différence réelle entre
type(mytype) :: x
x = mytype(0)
et
type(mytype) :: x
x = init_mytype(0)
et quel est le point entier d'utiliser le bloc d'interface interne mymod MODULE.
Eh bien, honnêtement, il y a une différence, l'énorme - la première est trompeuse. Cette fonction n'est pas le constructeur (car il n'y a aucun constructeur OOP dans Fortran), c'est un initialiseur.
dans le constructeur POO grand public est responsable de faire successivement deux choses:
- allocation de mémoire.
- Initialisation de membre. Jetons un coup d'oeil à quelques exemples d'instanciation de classes dans des langues différentes.
Dans Java:
MyType mt = new MyType(1);
un fait très important est caché - le fait que l'objet est en fait un pointeur vers une varibale d'un type de classe. L'équivalent en C++ sera allocation sur tas utilisant:
MyType* mt = new MyType(1);
Mais dans les deux langues, on peut voir que deux fonctions de constructeur se reflètent même au niveau de la syntaxe. Il se compose de deux parties: mot-clé new (allocation) et nom du constructeur (initialisation). Dans Objective-C syntaxe est encore plus insisté sur ce fait:
MyType* mt = [[MyType alloc] init:1];
Plusieurs fois, cependant, vous pouvez voir une autre forme d'invocation du constructeur. Dans le cas de l'allocation sur pile C++ utilise la construction de syntaxe spéciale (très pauvres)
MyType mt(1);
qui est en fait trompeur que nous ne pouvons tout simplement pas le considérer.
Dans Python
mt = MyType(1)
à la fois le fait que l'objet est en fait un pointeur et le fait que ont lieu d'affectation d'abord sont cachés (au niveau de la syntaxe). Et cette méthode est appelée ... __init__
! O_O Donc, c'est trompeur. L'allocation de pile С ++ s'estompe par rapport à celle-là. =)
Quoi qu'il en soit, l'idée d'avoir constructeur dans la langue implique la possibilité de faire l'allocation une initialisation dans une instruction à l'aide de la méthode une sorte spéciale. Et si vous pensez que c'est "vrai OOP", j'ai de mauvaises nouvelles pour vous. Même Smalltalkdoesn't have constructors. C'est juste une convention d'avoir une méthode new
sur les classes elles-mêmes (ce sont des objets singleton de méta-classes). Le Factory Design Pattern est utilisé dans de nombreuses autres langues pour atteindre le même objectif.
J'ai lu quelque part que les concepts de modules dans Fortran étaient inspirés par Modula-2. Et il semble pour moi que les fonctionnalités OOP sont inspirées par Oberon-2. Il n'y a pas non plus de constructeurs à Oberon-2. Mais il y a bien sûr une allocation pure avec une procédure pré-déclarée NEW (comme ALLOCATE dans Fortran, mais ALLOCATE est une déclaration). Après l'allocation, vous pouvez (en pratique) appeler un initialiseur, qui est juste une méthode ordinaire. Rien de spécial là-bas.
Vous pouvez donc utiliser une sorte d'usine pour initialiser des objets. C'est ce que vous avez réellement fait en utilisant des modules au lieu d'objets singleton. Ou il est préférable de dire qu'ils (programmeurs Java/C#/...) utilisent des méthodes objets singleton au lieu de fonctions ordinaires en raison de l'absence de la dernière (pas de modules - pas moyen d'avoir des fonctions ordinaires, seulement des méthodes).
Vous pouvez également utiliser SUBROUTINE lié au type à la place.
MODULE mymod
TYPE mytype
PRIVATE
INTEGER :: x
CONTAINS
PROCEDURE, PASS :: init
END TYPE
CONTAINS
SUBROUTINE init(this, i)
CLASS(mytype), INTENT(OUT) :: this
INTEGER, INTENT(IN) :: i
IF(i > 0) THEN
this%x = 1
ELSE
this%x = 2
END IF
END SUBROUTINE init
END
PROGRAM test
USE mymod
TYPE(mytype) :: x
CALL x%init(1)
END PROGRAM
INTENT(OUT)
pour this
arg de init
SUBROUTINE semble bien. Parce que nous attendons que cette méthode soit appelée seulement une fois et juste après l'allocation. Cela pourrait être une bonne idée de contrôler que cette hypothèse ne sera pas fausse. Pour ajouter un drapeau booléen LOGICAL :: inited
à mytype
, vérifiez s'il est .false.
et réglez-le sur .true.
lors de la première initialisation, et faites autre chose lors de la tentative de réinitialisation. Je me souviens certainement de quelque chose à ce sujet dans Google Groupes ... Je ne le trouve pas.
merci, fixé. Toutes mes excuses pour l'erreur distrayante, c'était un exemple précipité. –