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

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    mai 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mai 2012
    Messages : 53
    Points : 42
    Points
    42
    Par défaut Utilisation fonction d'un autre fichier cpp dans le main
    Bonjour a tous,

    Je travaille sur un programme en C++, à partir d'un projet existant.
    J’ai créé des fichiers .h et .cpp en dupliquant des fichiers existants car je souhaite les utiliser similairement pour ma partie.
    Je souhaite ensuite utiliser les fonctions de ces fichiers dans mon main.cpp
    Malheureusement, n’étant pas expert en C++, j’ai un peu du mal a comprendre comment faire au vu de la complexité des déclarations…
    Voila en gros mon code :

    ACPUSerialConnection.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace Communications {
     
    class LIBRARY_ACPU ACPUSerialConnection : public SerialConnection
    {
    	public:
    		virtual ~ACPUSerialConnection();
    		virtual bool processRequests( void );
                    [...]
     
    }
    ACPUSerialConnection.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    namespace Communications {
     
    bool ACPUSerialConnection::processRequests( void )
    {
            [mon code]
    }
    }
    Main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include "ACPUSerialConnection.h"  // Que cet include soit présent ou non ne change rien
     
    [...]
     
    bool CMIT_ACPU::SendCPUCode(void)
    {
    	bool reqInProgress = ACPUSerialConnection::processRequests();
    }

    J'ai les erreurs de compilation suivante dans le main:
    Erreur C2653: 'ACPUSerialConnection': l'identifiant n'est ni un nom de classe ni un nom d'espace de nom.
    Erreur C3861: 'processRequests': identifiant introuvable

    Si je demande a Visual Studio de me chercher la déclaration des différents membres de ma ligne de code du main, il les trouve sans problèmes.

    PS: Bien entendu, les fichiers qui m'ont servi a dupliqué ne sont plus utilisés dans le reste du programme, donc je ne peux pas m'appuyer dessus pour faire pareil...

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 266
    Points : 27 935
    Points
    27 935
    Par défaut
    Salut,

    Pour bien comprendre l'idée, tout ce que tu place entre les accolades qui délimitent ta classe devient automatiquement membre de ta classe (qu'il s'agisse d'une fonction ou d'une donnée), et, à ce titre, dépendra d'une instance particulière de ta classe.

    Les deux fois deux points :: représentent ce que l'on appelle "l'opérateur de portée" que l'on utilise lorsque l'on doit utiliser ce que l'on appelle le "nom pleinement qualifié" de quelque chose :

    1. quand on veut accéder à une fonctionnalité qui se trouve dans un espace de nom (par exemple Communication::ACPUSerialConnection laConnection;
    2. quand on veut définir le comportement d'une fonction membre (comme dans le fichier ACPUSerialConnection.cpp )
    3. quand on a affaire à une fonction qui ne dépend d'aucune instance de la classe (j'en parlerai plus tard)


    Pour pouvoir accéder à un membre de la classe (dans la limite de l'accessibilité de la fonction ou de la donnée), tu as besoin d'une instance de la classe ( une variable du type de la classe en question ) et tu y accède, classiquement, à l'aide de l'opérateur "point" . (si tu dispose de l'instance de la classe sous forme de valeur ou sous forme de référence) ou à l'aide de l'opérateur "fleche" -> si l'instance en question est un pointeur).

    Par exemple:
    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
    20
    21
    22
    23
    24
    25
    26
    /* Soit la classe */
    class MaClasse{
    public:
        void foo(){ /* ... */}
    };
    /* soit une fonction prenant une référence sur une instance existante de la classe */
    void bar(MaClasse & ref){
        /* on peut appeler MaClasse::foo() à partir de ref en utilisant le point '.'*/
        ref.foo();
    }
    /* et une fonction qui prend une instance de la classe sous forme de pointeur */
    void truc(MaClasse & ptr){
        /* on peut appeler MaClasse::foo() à partir de ptr en utilisant la flèche '->'*/
       ptr->foo()
    }
    int main(){
        /* on a besoin d'une instance de la classe */
       MaClasse obj;
       /* on peut transmettre cette instance à la fonction bar, qui va faire appel à la fonction foo */
       bar(obj);
       /* mais on peut aussi appeler la fonction foo directement à partir  de obj */
       obj.foo();
       /* Quand on n'a pas le choix, on travaille parfois avec des pointeurs (de préférence intelligents) */
       std::unique_ptr<MaClasse> ptr = std::make_unique<MaClasse>();
       truc(ptr.get());
    }
    Enfin, il faut savoir qu'il existe deux types très particuliers de fonctions membres:
    • les fonctions virtuelles, qui permettent de redéfinir le comportement de la fonction dans une classe dérivée (et d'obtenir un comportement polymorphe) et
    • les fonctions statiques, qui ne dépendent d'aucune instance de la classe en particulier (mais qui, du coup, ne peuvent pas accéder aux données et au fonctions "normales", vu qu'elle ne dépend d'aucune instance).


    Les fonctions virtuelles s'utilisent exactement comme les autres fonctions membres : il n'y a clairement que le comportement (ce qu'elles vont faire) qui va changer, par exemple:
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    /* soit une classe de base */
    class Base{
    public:
        /* et une fonction dont on veut pouvoir redéfinir le comportement dans les classes dérivées */
        virtual void printMe() const{
            std::cout<<"I'm a base\n";
        }
    };
    /* et une autre classe qui hérite (dérive) de la classe de base */
    class Derived : public Base{
    public:
         /* pour laquelle on redéfini le comportement de printMe 
          * Note que, depuis C++11, on peut la marquer comme override, pour forcer le compilateur
          * à s'assurer qu'il s'agit bien de redéfinir le comportement d'une fonction existant dans la classe
          * de base et pour laquelle une telle redéfinition est possible
          */
        void printMe() const override{
            std::cout<<"I'm a derived\n";
        }
    };
    /* une fonction libre qui prend une base comme paramètre 
     * (sous forme de référence, pour profiter du polymorphisme
     */
    void callMe(Base const & b){
        /* et qui fait appel à printMe */
        b.printMe();
    }
     
    int main(){
        /* une instance de base */
        Base laBase;
        /* que l'on transmet à callMe */
        callMe(laBase); // affiche "I'm a base"
        /* et une instance de Derived */
        Derived laDerivee;
        /* qui peut -- grace à l'héritage -- être substituée
         * à une Base, partout ou une instance de Base est attendue 
         */
        callMe(laDerivee); // ca marche!
                           // mais affiche "I'm a Derived"
    }
    Pour ce qui est des fonctions statiques, vu qu'elles ne dépendent d'aucune instance particulière de la classe, il est fréquent que l'on utilise ... le nom pleinement qualifié de la fonction, sous une forme proche de
    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
    /* une classe pour l'exemple */
    class MaClasse{
    public:
        /* qui expose une fonction statique */
        static laFonction();
    };
    int main(){
        /* comme laFonction ne dépend d'aucune instance particulière, 
         * il est fréquent que nous y faisons appel en utilisant le nom pleinement
         * qualifié de la fonction :
         */
        MaClasse::laFonction();
        /* mais, si le hasard veut que l'on dispose d'une instance de la classe
         * on peut y faire appel d'une manière tout à fait normale 
         */
        MaClasse obj;
        obj.laFonction();
    }
    NOTA : j'ai pris la peine d'écrire énormément de commentaires dans le code. Ils fournissent énormément d'informations utiles et nécessaires à la compréhension. N'hésites donc pas à les lire

    Pour ce qui est de ton problème particulier, le compilateur te fourni toutes les informations dont tu as besoin pour le corriger, même si, sur ce coup, le message n'est pas forcément très clair

    Quand il te dit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Erreur C2653: 'ACPUSerialConnection': l'identifiant n'est ni un nom de classe ni un nom d'espace de nom.
    En gros, il se plaint de ne pas connaitre le terme ACPUSerialConnection et, dans un sens, c'est tout à fait normal car tu as placé ta classe dans l'espace de noms Communications.

    Cet espace de noms va créer une sorte de "boite de rangement" dans laquelle tu as placé ta classe ACPUSerialConnection, qui n'est, du coup, plus visible "du dehors de la boite" (comprend : des fonctions qui ne font pas partie de l'espace de noms). Pour pouvoir accéder à cette classe, tu doit donc utiliser le noms pleinement qualifé qui permet d'y avoir accès depuis l'endroit où tu te trouve.

    La fonction main se trouvant dans "l'espace de noms global" (l'espace de noms qui contient tous les autres espaces de noms, mais qui n'a pas de nom particulier, lui-même), pour pouvoir accéder à cette classe, tu devrais utiliser la forme de Communications::ACPUSerialConnection /* ... */Mais cela ne résoudra qu'une partie de ton problème, car tu as utilisé ... l'opérateur de portée pour faire appel à la fonction processRequests. Or, cet opérateur particulier ne fonctionne que ... pour les fonctions statiques alors que processRequests est une fonction ... virutelle.

    Pour pouvoir faire appel à cette fonction, tu dois donc disposer d'une instance de la classe ACPUSerialConnection, ce qui donnerait au final un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /* on crée une instance de la classe, à moins qu'on en dispose "par ailleur" */
    ACPUSerialConnection connection;
    /* on peut maintenant faire appel à la fonction */
    bool result = connection.processRequests();
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    mai 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mai 2012
    Messages : 53
    Points : 42
    Points
    42
    Par défaut
    Merci beaucoup pour ce tutoriel dédié et complet, j’y vois déjà bien plus clair !
    Je me doutais qu’il y avait un souci avec le namespace quelque part, mais j’étais quand même bien perdu...

    Néanmoins je n’arrive pas encore à compiler…
    Pour commencer, est-ce que le #include au début du main est nécessaire ou non ?

    Ensuite, j’en suis donc avec le code suivant dans le main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    bool CMIT_ACPU::SendCPUCode(void)
    {
    	Communications::ACPUSerialConnection connection;
    	bool reqInProgress = connection.processRequests();
    }
    Mais j’ai les erreurs de compilations suivantes :

    Sur la première ligne:
    Erreur C2653: 'Communications': l'identifiant n'est ni un nom de classe ni un nom d'espace de nom.
    Erreur C2065: 'ACPUSerialConnection': Identifiant non défini.
    Erreur C2146: L'erreur de syntaxe: ';' est requise avant l'identificateur 'connexion'.
    Erreur C2065: 'connexion': Identifiant non défini.
    Sur la deuxième ligne:
    Erreur C2065: 'connexion': identifiant non défini.
    Erreur C2228: Le côté gauche de '.processRequests' doit être une classe, une structure ou une union
    Si je rajoute le #include, j'ai une seule erreur qui est la suivante:
    erreur C2512: 'Communications::ACPUSerialConnection': la classe, la structure ou l'union n'a pas de constructeur par défaut.

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 266
    Points : 27 935
    Points
    27 935
    Par défaut
    Citation Envoyé par BartRoX Voir le message
    Néanmoins je n’arrive pas encore à compiler…
    Pour commencer, est-ce que le #include au début du main est nécessaire ou non ?
    Oui, bien sur! Parce que c'est cette ligne qui va permettre au compilateur de savoir:
    1. que l'espace de noms "Communications" existe
    2. qu'il existe une classe "ACPUSerialConnection" dans cet espace de noms
    3. que cette classe dispose d'une fonction processRequests


    Pour être précis : la directive #include va demander à un outil appelé "le préprocesseur" de copier dans le fichier main.cpp l'intégralité du contenu du fichier ACPUSerialConnection.h ainsi que le contenu des fichiers qui ont été inclus (de manière directe ou indirecte) dans le fichier en question par une directive #include, et ce, de manière récursive.

    Tout cela parce que le compilateur lit le code de la première ligne à la dernière, un peu à la manière dont tu lis un bon roman, de la première page à la dernière, avec la même restriction que toi : arrivé à la ligne 10, il ne "connait" que ce qu'il a rencontré les 9 premières lignes (tout comme tu ne sais que ce qui s'est passé les 9 première pages quand tu arrives à la page 10 de ton roman), sans savoir ce qui se passe à la ligne 11 ou 12 (tout comme tu ne sais pas encore ce qui se passera à la page 11 ou 12 de ton roman).

    Or, si le compilateur rencontre l'usage de "quelque chose" qu'il ne "connait pas", il n'est pas content, et il s'arrête sur une erreur après te l'avoir fait savoir.
    Sur la première ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Erreur C2653: 'Communications': l'identifiant n'est ni un nom de classe ni un nom d'espace de nom.
    Erreur C2065: 'ACPUSerialConnection': Identifiant non défini.
    Erreur C2146: L'erreur de syntaxe: ';' est requise avant l'identificateur 'connexion'.
    Erreur C2065: 'connexion': Identifiant non défini.
    Sur la deuxième ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Erreur C2065: 'connexion': identifiant non défini.
    Erreur C2228: Le côté gauche de '.processRequests' doit être une classe, une structure ou une union
    La première erreur est toujours la plus importante, celle qui doit impérativement être corrigée. Parce qu'il arrive "régulièrement" que le compilateur continue à analyser le code malgré le fait qu'il ait rencontré une erreur; et que l'erreur en question fasse "perdre les pédales" au compilateur, qui va, du coup, afficher des "faux positifs" : des erreurs qui n'en sont en réalité pas.

    Dans le cas présent, il se plaint de ne pas connaitre l'identifiant Communications (qui correspond à ton espace de noms), ce qui est normal, si tu ne rajoute pas le fichier d'en-tête. Mais, du coup, il ne connait pas non plus ACPUSerialConnection pour la même raison, et il ne comprend donc pas que connection correspond au nomd d'une variable de type Communications::ACPUSerialConnection.

    Et, bien sur, comme il ne comprend pas ce que vient faire connection dans cette histoire, il va se plaindre qu'il aurait fallu un symbole de fin d'instruction avant le terme connection.

    Enfin, comme il n'a pas compris que connection était le nom d'une variable de type Communications::ACPUSerialConnection, il te dit que seuls les classes, les structures et les unions accepte la syntaxe "xxx.yyy" qui permet d'accéder au membres (de classes, de structure ou d'union)

    Comme tu peux t'en rendre compte, toutes ces erreurs ont la même origine, ou du moins la même solution : il faut que le compilateur lise le contenu du fichier ACPUSerialConnection.h avant d'arriver à cette ligne
    Si je rajoute le #include, j'ai une seule erreur qui est la suivante:
    erreur C2512: 'Communications::ACPUSerialConnection': la classe, la structure ou l'union n'a pas de constructeur par défaut.
    Ca, c'est une erreur de ma part, occasionnée par une information dont je ne disposais pas. Mais dont la solution ne consiste absolument pas à supprimer l'inclusion du fchier ACPUSerialConnection.h :

    Le code Communications::ACPUSerialConnection connection; essaye de créer une variable de type Communications::ACPUSerialConnection en partant du principe qu'il existe un constructeur par défaut (comprends: un constructeur ne nécessitant aucun paramètre pour pouvoir fonctionner). De toute évidence, ce n'est pas le cas; sans doute parce que tu as une ligne qui ressemble à ACPUSerialConnection(/* un ou plusieurs paramètres*/); dans le fichier d'en-tête.

    Il faut savoir que le compilateur ne va générer un constructeur par défaut que si ... tu ne lui donne aucune raison de faire autrement; et qu'il considère le simple fait que tu déclares un constructeur prenant un (ou plusieurs) paramètres comme "une raison suffisante" pour ne pas générer le constructeur par défaut.

    Selon le cas, il faudra donc soit
    • envisager de transmettre les paramètres "qui vont bien" pour permettre d'appeler le constructeur qui existe ou
    • envisager de déclarer (et de définir, bien sur) le constructeur "par défaut", à condition bien sur que cela ait du sens de le faire
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre du Club
    Homme Profil pro
    Inscrit en
    mai 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mai 2012
    Messages : 53
    Points : 42
    Points
    42
    Par défaut
    Merci encore d’avoir pris le temps de me répondre avec autant de détails.

    Effectivement, je n’y avais pas prêté attention mais il y a un constructeur, avec des paramètres, déclaré en protected en dessous dans le .h

    Hum... Maintenant il va falloir que je trouve quoi mettre dans ces paramètres...

    C'est donc à la déclaration de la variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Communications::ACPUSerialConnection connection;
    qui devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Communications::ACPUSerialConnection connection( mes paramètres );
    C’est bien ça ?

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 266
    Points : 27 935
    Points
    27 935
    Par défaut
    C'est bien cela...

    Mais si le constructeur est déclaré protected, tu vas avoir un sérieux problème, car cela implique qu'il n'est accessible qu'aux fonctions membre de ACPUSerialConnection et aux fonctions membres des classes qui en dérivent (s'il y en a). Tu ne pourras sans doute pas y faire appel depuis la fonction SendCPUCode de CMIT_ACPU (à moins que CMIT_ACPU ne dérive de ACPUSerialConnection, mais cela impliquerait une erreur de conception majeure, vu qu'un ACPU n'a absoluement rien à voir avec une ... connection )

    Ne sachant rien de ton projet ou de la bibliothèque que tu essayes d'utiliser (car, à voir tes questions, ce n'est pas ton code à toi ), j'entrevois cependant (au moins) trois solutions possibles, mais seule la documentation de la bibliothèque pourra t'indiquer laquelle est la bonne (et cela pourrait être une solution à laquelle je n'ai pas pensé) :

    1- la classe ACPUSerialConnection peut avoir été conçue selon le patron de conception singleton (quelle horreur).

    Dans ce cas, tu devrais avoir une fonction statique (précédée du mot clé static) nommée (get)Instance ou peut-être même (get)Connection dans la classe ACPUSerialConnection ou peut-être même au niveau de la classe SerialConnection dans l'accessibilité publique.

    Pour accéder à l'instance de cette classe tu devrais alors avoir recours à un code proche (selon le prototype de cette fonction) de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ACPUSerialConnection & instance =ACPUSerialConnection::Instance();
    bool reqInProgress = connection.processRequests();
    si cette fonction renvoie une référence ou proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ACPUSerialConnection * instance =ACPUSerialConnection::Instance();
    bool reqInProgress = connection->processRequests();
    (en adaptant bien sur le nom de la fonction appelée, que j'ai nommée Instance() au nom de la fonction statique que tu auras trouvée )

    2- il se peut (ce serait déjà mieux qu'un singleton, même si le principe reste sensiblement le même) que tu trouve une fonction amie dans le corps de la classe ACPUSerialConnection, qui serait déclarée sous une forme proche defriend ACPUSerialConnection & un_nom_quelconque(/* paramètres nécessaires */);. L'utilisation d'une telle fonction se ferait alors sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ACPUSerialConnection & connection = le_nom_de_la_fonction_amie(/* paramètres nécessaires */);
    bool reqInProgress = connection.processRequests();
    3- Il se peut enfin que tu sois face à ce que l'on appelle une classe abstraite (ce que les javaistes appelleraient volontiers une "interface") : une classe dont on ne peut pas créer directement une instance, mais que l'on peut utiliser, par exemple, comme type lors d'un passage de paramètres à une fonction.

    Dans ce cas, il y aura une classe qui dérive de ACPUSerialConnection, qui pourra donc faire appel au constructeur protégé de cette classe, et qu'il te faudra dénicher .

    Dans le pire des cas, ce sera à toi de créer cette classe dérivée.

    Mais si nous en arrivons à ce point (devoir créer toi même la classe dérivée de ACPUSerialConnection), et même bien avant d'en arriver là, je crains fort que tu n'aies, à l'heure actuelle, absolument pas le niveau nécessaire en C++ pour pouvoir profiter de cette bibliothèque.

    Je souhaiterais que tu évites absolument de prendre cette remarque comme une attaque, car elle ne veut absolument pas en être une : c'est une constatation froide et raisonnable issue des questions que tu as posées durant cette discussion, et qui se rapproche du problème qui se pose à tout débutant : pour pouvoir faire des choses "complexes" en C++ (comme essayer de tirer parti d'une bibliothèque de communication avec des ports série) il faut une "certaine maitrise" du langage qui ne s'obtient qu'avec... un minimum d'entrainement.

    Comprends bien que je n'ai aucun grief contre toi, et que je suis tout à fait disposé à continuer à t'aider dans ta démarche. Mais, en me basant sur ma propre expérience, je crains que si tu persiste dans ce projet avant d'avoir pris un peu de bouteille, tu ne finisse par te décourager complètement et par abandonner purement et simplement le développement en général (et en C++ en particulier).

    Si j'avais un conseil à te donner, ce serait sans doute de poser ce projet sur un coin de ton bureau "en attente de jours meilleurs", de commencer par t'atteler à l'étude du développement (en général) et du C++ (en particulier) et d'attendre de te sentir "plus à l'aise" avec toutes les notions que cela sous entend avant de ressortir ce projet en ayant -- enfin -- une chance d'obtenir un résultat probant
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre du Club
    Homme Profil pro
    Inscrit en
    mai 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mai 2012
    Messages : 53
    Points : 42
    Points
    42
    Par défaut
    Encore une fois merci pour ta réponse.
    Je ne le prends pas mal, c’est la vérité. Je n’ai pas un niveau d’expert en C++ et je me retrouve plongé dans un programme plutôt complexe, d’un niveau très avancé.
    Malheureusement je n’ai pas le choix car c’est mon travail, je dois donc me débrouiller d’une façon ou d’une autre et y arriver. En plus le temps presse…

    Je regarde (depuis hier déjà) ce que je peux faire grâce à ce que tu m’as dit.

Discussions similaires

  1. [Python 2.X] utiliser des fonction d'un autre fichier se trouvant dans le meme dossier
    Par nivlem dans le forum Général Python
    Réponses: 9
    Dernier message: 19/01/2018, 17h58
  2. Utilisation fonction d'un autre fichier
    Par thais781 dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 02/08/2014, 02h31
  3. appel d'une fonction dans un autre fichier jss
    Par Davee dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 28/06/2008, 20h12
  4. appel d'une fonction dans un autre fichier
    Par funboard dans le forum Langage
    Réponses: 2
    Dernier message: 08/02/2008, 09h26
  5. Comment utiliser les fonctions d'un autre fichier?
    Par zuzuu dans le forum Général Python
    Réponses: 8
    Dernier message: 14/12/2006, 18h22

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