Bonjour,
J'ai fait face à un problème étrange pour une des fonctions membres "getParam()" d'une classe "figure".
Ne faisant qu'une ligne, j'ai voulu la définir de façon explicite en utilisant le mot-clef inline, comme d'autres fonctions membres similaires de la classe :
g++ me fournit alors l'erreur suivante lors de l'édition des liens :
Code : Sélectionner tout - Visualiser dans une fenêtre à part inline int figure::getParam(void) { return param; }
Alors que tout fonctionne très bien pour d'autres fonction membres de ma classe...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 geom_glut.o: In function `ProcessSelection(int, unsigned int, unsigned int*)': geom_glut.cpp:(.text+0xc9d): undefined reference to `figure::getParam()' collect2: ld returned 1 exit status
J'ai alors eu l'idée de la définir de façon explicite dans le fichier d'en-tête figure.h :
Et surprise cela fonctionne...
Code : Sélectionner tout - Visualiser dans une fenêtre à part int getParam(void) { return param; };
Je suis désespérament à la recherche d'une explication rationnelle! Merci d'avance si vous pouvez m'aider.
Ci-dessous, ma classe :
- figure.h
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 #ifndef GEOM_CLASS_H #define GEOM_CLASS_H #include <list> /****** Structure color ******/ struct color { float c[3]; void use(void) const; }; /****** classe figure ******/ class figure { protected : std::list< figure* > parents; /* Objets dont dépend la figure */ std::list< figure* > children; /* Objets dépendant de la figure */ bool locked; /* Vérouillé? */ bool defined; /* Défini? */ int col; /* Indice couleur */ float width; /* Épaisseur tracé */ int type; /* Type de figure (ex : POINT, LINE etc...) */ int param; /* Paramètres définissant la figure (ex : POINT_LINE) */ int time; /* Quand l'objet a été crée */ static int clock; /* pour savoir quand les objets sont crées les uns par rapport aux autres */ public : figure(int p); bool getLocked(void); void changeLocked(void); bool getDefined(void); void setDefined(bool b); int getColor(void); void setColor(int n); int getType(void); int getParam(void) { return param; }; void Delete(std::list< figure* >& l); /* Liste les objets à détruire si this l'est */ virtual int Add(figure* fig){}; /* Ajoute un objet parent et renvoie true si la construction de l'objet est finie */ virtual void Update(void); /* Mets à jour les pptés de l'objet et les dépendances */ virtual void Draw(void){}; /* Trace la figure */ virtual void Preview(float& x, float& y){}; /* Trace une figure en cours de création */ virtual bool getPoint(float& a, float& b){}; /* Obtient les coordonnées de this */ }; /****** classe point ******/ class point : public figure { protected : float px; float py; // char label; public : point(float x, float y); point(int p); virtual int Add(figure* fig); virtual void Update(void); virtual void Draw(void); virtual void Preview(float& x, float& y); virtual bool getPoint(float& x, float& y); }; /****** classe line ******/ /* class line : public figure { public : line(); virtual void Update(){}; virtual void Draw(){}; }; */ /****** classe circle ******/ /* class circle : public figure { public : circle(); virtual void Update(){}; virtual void Draw(){}; }; */ /****** classe tri ******/ /* class tri : public figure { public : tri(); virtual void Update(){}; virtual void Draw(){}; }; */ /****** classe quad ******/ /* class quad : public figure { public : quad(); virtual void Update(){}; virtual void Draw(){}; }; */ /****** classe polygon ******/ /* class polygon : public figure { public : polygon(); virtual void Update(){}; virtual void Draw(){}; }; */ #endif /* GEOM_CLASS_H */- geom_class.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 #include <iostream> #include "geom_main.h" using namespace std; /****** Structure color ******/ void color::use(void) const { glColor3fv(c); } /****** classe figure ******/ int figure::clock = 0; figure::figure(int p) { locked = false; defined = true; col = WHITE; param = p; width = 1.; time = clock++; } inline bool figure::getLocked(void) { return locked; } inline void figure::changeLocked(void) { locked = !locked; } inline bool figure::getDefined(void) { return defined; } inline void figure::setDefined(bool b) { defined = b; } inline int figure::getColor(void) { return col; } inline void figure::setColor(int n) { col = n; } inline int figure::getType(void) { return type; } void figure::Update() { defined = true; /* Si un des objets dont dépend this n'est pas défini c'est inutile */ list< figure* >::iterator i; for (i = parents.begin(); i!=parents.end(); i++) { if ( !( (*i) -> getDefined() ) ) { defined = false; return; } } } void figure::Delete(list< figure* >& l) { list< figure* >::iterator i; /* Ajoute les points spécialement crée lors de la création de this */ for (i = parents.begin(); i != parents.end(); i++) { if ( ((*i) -> time) > time ) { l.push_back(*i); } } /* Recommence l'opération pour tous les descendants de this */ for (i = children.begin(); i != children.end(); i++) { (*i) -> Delete(l); } } /****** classe point ******/ point::point(float x, float y) : figure(POINTPOINT_POINT) { width = 2.0; type = POINT; px = x; py = y; } point::point(int p) : figure(p) { width = 2.0; type = POINT; } int point::Add(figure* fig) { switch (param) { case POINTPOINT_POINT : if ( (fig -> getType()) != POINT ) return NOTADDED; fig -> getPoint(px, py); return DONE; break; case POINTMIDDLE_POINT_POINT : if ( (fig -> getType()) != POINT ) return NOTADDED; parents.push_back(fig); if ( parents.size() == 2) { Update(); return DONE; } else return ADDED; break; } } void point::Update(void) { figure::Update(); list< figure* >::iterator i; float x1, y1, x2, y2; switch (param) { case POINTPOINT_POINT : break; case POINTMIDDLE_POINT_POINT : parents.front() -> getPoint(x1, y1); parents.back() -> getPoint(x2, y2); px = x1/2. + x2/2.; py = y1/2. + y2/2.; break; // case POINTMIDDLE_SEGMENT : // break; } /* Application des changements aux objets dépendant de *this */ for (i = children.begin(); i!=children.end(); i++) { (*i) -> Update(); } } void point::Draw(void) { if (!defined) return; glPointSize(width); colormap[col].use(); glBegin(GL_POINTS); glVertex2f(px,py); glEnd(); } void point::Preview(float& x, float& y) { switch (param) { case POINTMIDDLE_POINT_POINT : if (parents.empty()) return; point p(x,y); parents.push_back(&p); Update(); Draw(); defined = false; parents.pop_back(); break; } } bool point::getPoint(float& x, float& y) { x = px; y = py; return defined; }- et le header geom_main.h qui contient les enum nécessaires :
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 #ifndef GEOM_MAIN_H #define GEOM_MAIN_H /****** Headers ******/ #include <GL/glui.h> #include <GL/freeglut.h> #include <GL/glu.h> #include <GL/gl.h> #include "geom_class.h" /****** Constantes ******/ extern const float M; /* Dimension zone de dessin carrée */ extern const int BORD; /* Largeur des bords de la fenêtre pour déplacement */ extern const char *obj_name[6]; /* Noms figures (Point, ...) */ enum { /* figures */ POINT = 0, LINE, CIRCLE, TRI, QUAD, POLYGON, NONE }; enum /* Bouttons souris */ { MOUSE_LEFT_BUTTON = 0, MOUSE_MIDDLE_BUTTON = 1, MOUSE_RIGHT_BUTTON = 2, MOUSE_SCROLL_UP = 3, MOUSE_SCROLL_DOWN = 4 }; enum /* Position souris par rapport à fenêtre */ { MOUSE_OUTSIDE = 0, MOUSE_INSIDE = 1, MOUSE_JUSTINSIDE = 2 /* Pour prévenir un conflit avec glui */ }; enum /* Réponse possible lors de l'ajout d'une figure lors de la construction d'un objet */ { NOTADDED = 0, ADDED = 1, DONE = 2 }; enum /* Menu Principal */ { /* Modes */ RADIOBUTTON_MODE_EDIT = 0, RADIOBUTTON_MODE_DRAW = 1, /* Boutons*/ BUTTON_MOVEORIGIN, BUTTON_RESETZOOM, RADIOBUTTON_MODE, LISTBOX_OBJ, BUTTON_CLEAR, BUTTON_QUIT }; enum /* Menu Point */ { /* Types */ POINTPOINT_POINT, POINTMIDDLE_POINT_POINT, POINTMIDDLE_SEGMENT, POINTINTERSECTION, /* Boutons */ POINT_PROPERTIES_LOCKED, POINT_PROPERTIES_LABEL, POINT_PROPERTIES_DELETE }; /* Couleurs */ const color black = {0.0, 0.0, 0.0}, red = {1.0, 0.0, 0.0}, green = {0.0, 1.0, 0.0}, blue = {0.0, 0.0, 1.0}, cyan = {0.0, 1.0, 1.0}, yellow = {1.0, 1.0, 0.0}, magenta = {1.0, 0.0, 1.0}, white = {1.0, 1.0, 1.0}; const color colormap[8] = {black, red, green, blue, cyan, yellow, magenta, white}; enum { BLACK = 0, RED, GREEN, BLUE, CYAN, YELLOW, MAGENTA, WHITE }; /****** Variables Globales ******/ /* Fenêtre Graphique */ extern float X, Y; /* Coordonnées coin gauche fenêtre */ extern float lX, lY; /* Dimensions fenêtre */ extern int Xview, Yview; /* Dimensions viewport */ extern int win_main; /* ID Fenêtre graphique */ /* Dessin */ extern std::list< figure* > figures; /* Figures du dessin */ extern figure* newobj; /* Figure courante */ /* Souris */ extern int xold, yold; /* Coordonnées souris */ extern int move; /* Déplacement centre fenêtre */ extern int mouse; /* Souris dans fenêtre? */ /* Elements Menu */ extern GLUI* glui_main; /* Menu principal */ extern GLUI* glui_edit[6]; /* Menus édition */ extern GLUI_Listbox* listbox_obj; /* Choix figure */ extern GLUI_Panel* panel_type[6]; extern GLUI_Panel* panel_properties[6]; extern GLUI_Listbox* listbox_type[6]; /* Menu : Live Variables */ extern int menu_view_axis; extern int menu_view_square; extern int menu_view_coord; extern int menu_mode; /* Mode : Edit ou Draw */ extern int menu_obj; /* Figure courante */ extern int menu_obj_old; /* Précédente figure courante */ extern int obj_type; /* Objet courant */ /****** Fonctions geom_glut.cpp ******/ /*** Affichage ***/ /* Freeglut Callback functions */ void Reshape(int width, int height); void Display(void); /* Gestion zoom & déplacements */ void Zoom(float a, float x, float y); void TestPosition(void); /* Si la zone d'affichage est bien dans la zone de dessin */ /*** Souris ***/ /* Freeglut Callback functions */ void Mouse(int button, int state, int x, int y); void Motion(int x, int y); void PassiveMotion(int x, int y); void TestMouse(int state); /* Si la souris sors de la fenêtre */ void TestBords(); /* Si la souris est proche du bord de la fenêtre */ /* Conversions entre coordonnées souris et coordonnées réelles */ void Mouse2Coord(float & x, float & y); void Coord2Mouse(float & x, float & y); /* Sélection */ void ProcessSelection(int n, GLuint p, GLuint * selectBuf); /*** Clavier ***/ /* Freeglut Callback functions */ void KeyboardNormalKeys(unsigned char key, int x, int y); void KeyboardSplecialKeys(int key, int x, int y); /****** Fonctions geom_menu.cpp ******/ /* Menu Principal */ void MainCreateMenu(void); void MainProcessMenu(int n); /* Menus d'édition */ void CreateEditMenu(void); void InitEditMenu(void); void ProcessEditMenu(int n); void CreateNewFigure(void); void CancelNewFigure(void); #endif /* GEOM_MAIN_H */
Partager