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

C++ Discussion :

Instanciation d'une classe fille et problème accès aux méthodes de type private


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 60
    Points : 36
    Points
    36
    Par défaut Instanciation d'une classe fille et problème accès aux méthodes de type private
    Bonsoir,

    J'utilise pour ceux qui connaissent peut être la librairie GDAL (librairie de formats de données géospatiales) . J'ai la contrainte d'utiliser dans mon main.cpp deux objets, c'est-à-dire l'instanciation d'une classe mère ( GDALDataset) et d'une classe fille (netCDFDataset) , de la manière suivante :

    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
     
    #include "gdal_priv.h"
    #include "netcdfdataset.h"
     
    #define TRUE 1
     
    int main() {
     
      GDALAccess eAccess;
      double a=10.0;
     
      GDALDataset *mother = (GDALDataset*) GDALOpen("seed_3d.dgn", eAccess);
      netCDFDataset child;
      child.SetDefineMode(TRUE);
     
      ((netCDFDataset*) mother)->SetGeoTransform(&a);
     
    }
    Comme vous pouvez le voir, J'instancie d'abord l'objet mother grâce à l'ouverture du fichier "see_3d.dgn".

    puis j'instancie de manière statique l'objet child.

    Vous pouvez voir que pour une bonne compilation, je suis obligé de rajouter, en plus du header de la librairie de GDAL ( "gdal_priv.h" ), le header du prototype de la classe fille, c'est-à-dire le fichier "netcdfdataset.h".

    Voici le message obtenu à la compil si je n'inclus pas le header "netcdfdataset.h" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    main.cpp: In function 'int main()':
    main.cpp:12:2: error: 'netCDFDataset' was not declared in this scope
    Or pour générer la librairie GDAL (libgdal.so), je me suis déjà servi du header "netcdfdataset.h" ainsi que le fichier de défintion "netcdfdataset.cpp" (qui sont tous les deux dans les sources de la librairie GDAL).

    Il y a donc un premier problème, c'est-à-dire pouvoir instancier une classe fille avec seulement le header de la classe mère, mais ceci n'a pas l'air d'être possible...

    Bon, admettons que je sois obligé d'utiliser le fichier de prototype "netcdfdataset.h".

    Avec le bout de code du début, j'obtiens maintenant l'erreur ci-dessous à la compil.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    In file included from main.cpp:2:0:
    netcdfdataset.h: In function 'int main()':
    netcdfdataset.h:642:9: error: 'int netCDFDataset::SetDefineMode(int)' is private
    main.cpp:13:26: error: within this context
    avec les commandes de compil suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    g++ -I/usr/local/gdal/include -I. -L/usr/local/gdal/lib -c main.cpp
    g++ -L/usr/local/gdal/lib -lgdal main.o -o test_gdal
    Pour mieux comprendre ce message d'erreur ( error: 'int netCDFDataset::SetDefineMode(int)' is private ), j'ai regardé le prototype de netCDFDataset; voici ce prototype :

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    /************************************************************************/
    /* ==================================================================== */
    /*			     netCDFDataset		                             		*/
    /* ==================================================================== */
    /************************************************************************/
    
    class netCDFRasterBand;
    
    class netCDFDataset : public GDALPamDataset
    {
        friend class netCDFRasterBand; //TMP
    
    // RAJOUT AVEC LAQUELLE IL N'Y A PAS D'ERREUR DE COMPIL
        //public:
    // END RAJOUT
    
        /* basic dataset vars */
        CPLString     osFilename;
        int           cdfid;
        char          **papszSubDatasets;
        char          **papszMetadata;
        CPLStringList papszDimName;
        bool          bBottomUp;
        int           nFormat;
        int           bIsGdalFile; /* was this file created by GDAL? */
        int           bIsGdalCfFile; /* was this file created by the (new) CF-compliant driver? */
    
        /* projection/GT */
        double       adfGeoTransform[6];
        char         *pszProjection;
        int          nXDimID;
        int          nYDimID;
        int          bIsProjected;
        int          bIsGeographic;
    
        /* state vars */
        int          status;
        int          bDefineMode;
        int          bSetProjection; 
        int          bSetGeoTransform;
        int          bAddedProjectionVars;
    
        /* create vars */
        char         **papszCreationOptions;
        int          nCompress;
        int          nZLevel;
        int          nCreateMode;
        int          bSignedData;
    
        double       rint( double );
    
        double       FetchCopyParm( const char *pszGridMappingValue, 
                                    const char *pszParm, double dfDefault );
    
        char **      FetchStandardParallels( const char *pszGridMappingValue );
    
        
        /* new */
        void ProcessCreationOptions( );
        int DefVarDeflate( int nVarId, int bChunking=TRUE );
        CPLErr AddProjectionVars( GDALProgressFunc pfnProgress=GDALDummyProgress, 
                                  void * pProgressData=NULL );
    
        int GetDefineMode() { return bDefineMode; }
        int SetDefineMode( int bNewDefineMode );
    
        CPLErr      ReadAttributes( int, int );
    
        void  CreateSubDatasetList( );
    
        void  SetProjectionFromVar( int );
    
      public:
    
        netCDFDataset( );
        ~netCDFDataset( );
        
        /* Projection/GT */
        CPLErr 	GetGeoTransform( double * );    
        CPLErr 	SetGeoTransform (double *);
        const char * GetProjectionRef();
        CPLErr 	SetProjection (const char *);
    
        char ** GetMetadata( const char * );
    
        int GetCDFID() { return cdfid; }
    
        /* static functions */
        static int Identify( GDALOpenInfo * );
        static int IdentifyFormat( GDALOpenInfo *, bool );
        static GDALDataset *Open( GDALOpenInfo * );
    
        static netCDFDataset *CreateLL( const char * pszFilename,
                                        int nXSize, int nYSize, int nBands,
                                        char ** papszOptions );
        static GDALDataset *Create( const char * pszFilename,
                                    int nXSize, int nYSize, int nBands,
                                    GDALDataType eType,
                                    char ** papszOptions );
        static GDALDataset* CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
                                        int bStrict, char ** papszOptions, 
                                        GDALProgressFunc pfnProgress, void * pProgressData );
            
    };
    Vous pouvez voir le rajout que j'ai fait au début du prototype pour que la compil se passe bien : j'ai rajouté le mot public pour que la méthode SetDefineMode soit accessible dans le main.cpp .

    Ceci n'est pas propre du tout, j'aimerais éviter de faire cette modification.

    On peut remarquer que la classe fille netCDFDataset est héritée de manière publique de la classe GDALPamDataset.

    Or d'après le diagramme de la classe GDALDataset (la classe mère dans mon main.cpp), on voit que GDALPamDataset hérite elle-même de GDALDataset :

    http://www.gdal.org/classGDALDataset.html

    Pourquoi dans la définition de la classe fille netCDFDataset, la méthode SetDefineMode est définie en private ? Est-ce une erreur de conception de la libriarie GDAL ?

    J'en suis arrivé à la conclusion suivante :

    étant donné que la méthode SetDefineMode n'est pas définie dans la méthode mère GDALDataset, même comme méthode virtuelle, je suis obligé, si je veux utiliser la
    classe 2ème fille netCDFDataset dans mon main.cpp, d'utiliser le header et la définition de netCDFDataset avec en plus, une modification pour avoir accès à la méthode SetDefineMode initialement en private.

    J'ai donc une sous boite noire netCDFDataset de la boite GDALDataset et il n'y a pas de lien entre les deux, c'est-à-dire avec une méthode définie uniquement dans la sous-boîte netCDFDataset.

    Merci par avance pour votre aide

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Ta méthode SetDefineMode() est sans doute supposée être utilisée par la classe netCDFRasterBand, déclarée comme amie de netCDFDataset.
    Tu n'es donc pas supposé l'utiliser directement.

    Je t'invite à lire la doc (pas la doc de référence) qui explique comment utiliser cette bibliothèque. Il y a sans doute une logique d'utilisation particulière.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 60
    Points : 36
    Points
    36
    Par défaut
    Merci pour ton aide. En effet, le mot-clé friend nous dirait que setDefineMode() est accessible via la classe amie netCDFRasterBand.

    mais malheureusement, elle n'est pas utilisée dans la définition de netCDFRasterBand.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    Il y a donc un premier problème, c'est-à-dire pouvoir instancier une classe fille avec seulement le header de la classe mère, mais ceci n'a pas l'air d'être possible...

    Bon, admettons que je sois obligé d'utiliser le fichier de prototype "netcdfdataset.h".
    C'est tout à fait normal. Pour utiliser une classe, il faut son header qui la définit.

    Vous pouvez voir le rajout que j'ai fait au début du prototype pour que la compil se passe bien : j'ai rajouté le mot public pour que la méthode SetDefineMode soit accessible dans le main.cpp .
    Bah oui, SetDefineMode est private, surement pour une raison. C'est là aussi normal que tu ne puisses pas l'utiliser dans le main.

    Concrètement, il n'y a aucun problème, sauf à ne pas comprendre la grammaire du C++ et à mal utiliser ces classes.
    Soit ce que tu veux faire est interdit, d'où l'accessibilité private de la méthode. Soit tu t'y prends mal, et il faut alors se référer à la doc des classes pour y parvenir.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. accès à une classe fille non instanciée
    Par a066043 dans le forum Langage
    Réponses: 4
    Dernier message: 06/10/2010, 14h15
  2. Instanciation d'une classe fille depuis une classe mère
    Par khaled-benloucif dans le forum Langage
    Réponses: 2
    Dernier message: 30/01/2009, 23h59
  3. Problème d'accès aux méthodes d'une classe
    Par RR instinct dans le forum Langage
    Réponses: 5
    Dernier message: 26/06/2006, 14h51
  4. Réponses: 6
    Dernier message: 01/05/2006, 19h05
  5. [TOMCAT] JSP problème d'accès aux méthodes d'une classes
    Par gunnm dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 22/05/2004, 14h02

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