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 :
Comme vous pouvez le voir, J'instancie d'abord l'objet mother grâce à l'ouverture du fichier "see_3d.dgn".
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); }
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" :
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).
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
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.
avec les commandes de compil suivantes :
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
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 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
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 .
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 ); };
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
Partager