IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Le type TMyObject n'est pas encore complètement défini


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Par défaut Le type TMyObject n'est pas encore complètement défini
    Bonjour tout le monde,

    voici ce que je cherche à faire :
    avoir 2 classes dans 2 unités différentes et chacune des classes ayant une référence du type de l'autre classe.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    type
      TMyObject = class( TComponent )
      private
        FMyObject2 : TMyObject2;
      end;
    Et faire de même dans la déclaration de TMyObject2.
    Bien entendu, on ne peut pas mettre dans les uses interface l'unité de l'autre classe, sinon on aurait des uses circulaires.

    Je me suis dit, qu'une solution serait de mettre TMyObject2 dans le uses de MyObject puis faire une prédéclaration de TMyObject dans l'unité de TMyObject2.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    type
      TMyObject = classs;
      TMyObject2 = class( TComponent )
      private
        FMyObject : TMyObject;
      end;
    Mais dans ce cas, j'ai le message d'erreur :
    Le type TMyObject n'est pas encore complètement défini.
    J'ai l'impression que je n'ai le droit de faire une prédéclaration que dans l'unité qui déclare la classe.

    Une solution serait de mettre les 2 classes dans la même unité, mais comme chaque classe est énorme (dépasse les milliers de ligne), je préfère les garder dans des unités séparées.

    Pour l'instant, j'ai un objet qui est l'owner de l'autre, donc je passe par l'owner et je transtype, c'est pas très propre mais ça marche tant que je n'ai pas d'autre solution.

    Est-ce que faire une prédéclaration est une bonne solution et il y a une astuce que j'ai zappé ou dois-je continuer à utiliser les owner car il n'y a pas d'autre solution ?

  2. #2
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    ce que tu veut faire ne peut pas ce faire directement
    il te faut passer par un ancetre de ta classe c'est les fameux probleme de reference circulaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Unit UMyClaseBase 
     TmyClassBase = TComponent 
     end;
    (****************************)
    unit UMyObject
    uses UMyClaseBase;
     type
      TMyObject = class( TComponent )
      private
        FMyObject2 : TmyClassBase;
      end;
    (****************************)
    unit MyObject2
    uses UMyClaseBase,UMyObject;
    type
      TMyObject2 = class(TmyClassBase)
      private
        FMyObject : TMyObject;
      end;
    @+ Phil

  3. #3
    Membre éclairé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Par défaut
    Salut Phil et merci de proposer une solution, mais en utilisant une classe mère, on est obligé de faire un transtypage pour pouvoir travailler avec, ce qui ne résoud pas vraiment mon problème, c'est comme en utilisant l'owner.

  4. #4
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 931
    Billets dans le blog
    6
    Par défaut
    ne serait-ce point une solution que d'utiliser des interfaces ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  5. #5
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Bonjour,

    Je ne sais pas si ça répond à la question, mais pour faire des références circulaires dans les clauses Uses de 2 units Unit1 et Unit2 , il suffit de mettre dans "uses Unit1" dans la partie implémentation de Unit2.

  6. #6
    Membre éclairé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Par défaut
    Salut Graffito mais avec ta méthode ça ne marche pas, je le fais déjà mais on ne peut pas utiliser chacune des classes dans l'autre dans la partie declaration, on est obligé d'en avoir une utilisée qu'à partir d'implementation et ce n'est pas ce que je désire faire.

    Salut tourlourou, j'ai essayé de faire une sorte d'utilisation d'interfaces sans utiliser des interfaces et j'ai eu ces messages d'erreur :
    Le type TMyObject n'est pas encore complètement défini.
    Par contre, utiliser des interfaces, ça n'oblige pas d'instancier des méthodes utiles pour les interfaces comme le compteur de références et d'autres choses galères à utiliser ?

    As-tu un exemple simple à montrer ?

  7. #7
    Expert confirmé

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Par défaut
    @Graffito : oui si une unité n'utilise le type de l'autre que dans sa partie implémentation Or là il s'agit bien d'avoir les références dans la partie interface des deux côtés (enfin c'est ce que j'ai cru comprendre).

    @WebPac : la solution est évidemment, comme tu l'as dit toi-même, de placer les deux classes dans la même unité. Même si elles font des milliers de lignes, c'est comme ça.

    Si l'on réfléchit un peu au sens du mot unité : il s'agit bien de construire une entité unique. À l'intérieur de cette entité, tout ou presque est possible : aussi bien faire des références circulaires entre classes qu'accéder aux variables privées d'autres classes. Mais dès qu'on sort de l'unité, celle-ci apparaît comme une enveloppe à laquelle on ne touche pas, si ce n'est en lecture à sa section interface.

    Il est donc par nature et par essence impossible de faire ce que tu veux.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 16
    Dernier message: 06/06/2007, 15h46
  2. Réponses: 6
    Dernier message: 23/12/2006, 17h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo