Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2502 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [C++] Problèmes à la compilation avec des fonctions amies

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C++] Problèmes à la compilation avec des fonctions amies

n°524203
Evadream -​jbd-
Posté le 26-09-2003 à 18:13:00  profilanswer
 

Salut à tous !
 
Je programme en C++ sous Linux à l'aide gcc. Et j'ai un petit problème à la compilation. Voici mon soucis :
 
J'ai une classe CSOFT_scene et une classe CLine. Cette dernière possède une fonction membre DrawLine, que je souhaite rendre amie avec la classe SOFT_scene. Voici comment je m'y suis pris :
 
Classe CLine (fichier CLine.h)

Code :
  1. class CLine {
  2.      [...]
  3.      void DrawLine(CSOFT_scene* ) ; /* Ligne 14 */
  4.      [...]
  5. };


 
Classe CSOFT_scene (fichier CSOFT_scene.h)

Code :
  1. class CSOFT_scene {
  2.       [...]
  3.       friend void CLine::DrawLine(CSOFT_scene* ) ; /* Ligne 15 */
  4.       [...]
  5. };


 
Voici le résultat de la compilation :
 
Résultat de la compilation


g++ -Wall -pedantic  -c main.cpp -o main.o
In file included from CLine.h:7,
                 from main.cpp:4:
CSOFT_scene.h:15: variable or field `CLine' declared void
CSOFT_scene.h:15: `CLine' is neither function nor member function; cannot be declared friend
CSOFT_scene.h:15: syntax error before `::' token
make: *** [main.o] Error 1


 
J'ai l'impression qu'il s'agit d'un simple problème de syntaxe :/
 
Je rajoute mon makefile :
 
Makefile


CC=g++
SDL = -lSDL
CFLAGS = -Wall -pedantic
CMATH = -lm
CDEBUT = -g
COPT = -O3
CPROG = resultat
 
 
std: main.o CLine.o CSOFT_scene.o
 $(CC) $(SDL) $(CFLAGS) $(CMATH) main.o CLine.o CSOFT_scene.o -o $(CPROG)
 
main.o: main.cpp
 $(CC) $(CFLAGS) -c main.cpp -o main.o
 
CLine.o: CLine.cpp
 $(CC) $(CFLAGS) -c CLine.cpp -o CLine.o
 
CSOFT_scene.o: CSOFT_scene.cpp
 $(CC) $(CFLAGS) -c CSOFT_scene.cpp -o CSOFT_scene.o
 
 
clean:
 rm -f resultat *.o
 


 
 
Merci pour votre aide !
 
@+
 
Edit 1 : Changement du résultat de la compilation, désolé.
Edit 2 : Rajout du makefile


Message édité par Evadream -jbd- le 27-09-2003 à 20:31:46
mood
Publicité
Posté le 26-09-2003 à 18:13:00  profilanswer
 

n°524207
Joel F
Real men use unique_ptr
Posté le 26-09-2003 à 18:20:10  profilanswer
 

hmmm tu ne peut pas declarer UNE methode d'une classe friend d'une autre.
 
Faut declarer une CLASSE friend de l'autre.
 
Classe CLine (fichier CLine.h)

Code :
  1. class CLine {
  2.     [...]
  3.     void DrawLine(CSOFT_scene* ) ; /* Ligne 14 */
  4.     [...]
  5. };


 
Classe CSOFT_scene (fichier CSOFT_scene.h)

Code :
  1. class CSOFT_scene {
  2.      [...]
  3.      friend class CLine; /* Ligne 15 */
  4.      [...]
  5. };

n°524211
Evadream -​jbd-
Posté le 26-09-2003 à 18:29:01  profilanswer
 

Ah bon ?  
 
J'ai lu dans "Le langage C++" de notre ami Bjarne Stroustrup :
 
La fonction membre d'une classe peut être l'amie d'une autre. [...]
 
L'exemple qui suit ds le bouquin reprend la même syntaxe que ci-dessus.
 
 

Code :
  1. class List_iterator {
  2.     // ...
  3.     int *next() ;
  4. }
  5. class List {
  6.      friend int* List_iterator::next() ;
  7.      // ...
  8. }


 
"Il n'est pas inhabituel que toutes les fonctions d'une classe  soient amies d'une autre [...]"
 
Et l'exemple qui suit reprend ta syntaxe :
 

Code :
  1. class List {
  2.      friend class List_iterator ;
  3. }


 
 
Que dois-je en conclure ? S'agit t'il d'une erreur ds le bouquin ? (dernière édition)
 
Merci à toi pour ta précédente réponse en tout cas !
 
@+

n°524212
Joel F
Real men use unique_ptr
Posté le 26-09-2003 à 18:31:11  profilanswer
 

le problème est que la différence entre les dires de notre ami Stroustrup et les spec des compilos est souvent enorme ...
 
tu essaieras la specialisation partielle de fonction tempalte, le mot clé export etc ...
 
Je pense juste que le compilo ne supporte pas les METHODES amieS.
Je vais néanmoins vérifier et tester ca :)
 
 
EDIT : euh tu includ bien le cline.h dans le CSOFT_scene.h ??


Message édité par Joel F le 26-09-2003 à 18:31:47
n°524219
Evadream -​jbd-
Posté le 26-09-2003 à 18:41:00  profilanswer
 

Merci pour ta rapide réponse !
 


le problème est que la différence entre les dires de notre ami Stroustrup et les spec des compilos est souvent enorme ...


 
Je n'en avais naïvement jamais douté ! Pour information, je travaille avec gcc 3.2.3.
 

EDIT : euh tu includ bien le cline.h dans le CSOFT_scene.h ??


 
Oui, je viens de (re)vérifier pour la cinquantième fois de l'après midi [:ddr555]
 
 
J'ai essayé de "passer" la classe CLine en friend comme tu me la proposé, à savoir :
 
Classe CSOFT_scene (fichier CSOFT_scene.h)

Code :
  1. class CSOFT_scene {
  2.     [...]
  3.     friend class CLine; /* Ligne 15 */
  4.     [...]
  5. };


 
 
Mais j'obtiens l'erreur suivante à la compilation, ce qui doit mettre en avant une autre faiblesse de mon code :
 
Résultat de la compilation


g++ -Wall -pedantic  -c main.cpp -o main.o
g++ -Wall -pedantic  -c CLine.cpp -o CLine.o
g++ -Wall -pedantic  -c CSOFT_scene.cpp -o CSOFT_scene.o
In file included from CSOFT_scene.h:9,
                 from CSOFT_scene.cpp:3:
CLine.h:14: `CSOFT_scene' was not declared in this scope
CLine.h:14: syntax error before `)' token
make: *** [CSOFT_scene.o] Error 1


 
Ca semble donc être ici un problème de portée. Mais je ne suis pas du tout sensibilisé à cela. La solution se trouve t'elle ds l'utilisation d'un namespace ?
 
Merci à vous !
 
Edit : je dois m'absenter pour la soirée ! A plus tard !


Message édité par Evadream -jbd- le 26-09-2003 à 18:43:49
n°524221
Joel F
Real men use unique_ptr
Posté le 26-09-2003 à 18:51:58  profilanswer
 

=> utilise gcc 3.3.1 le 3.2 est une usine a ICE.
 
=> a tu proteger tes .h apr des diretcive d'inclusions ??
 

Code :
  1. // debut du .h
  2. #ifndef _MONFICHIER_H_
  3. #define _MONFICHIER_H_
  4. // mon code
  5. #define

n°524226
Taz
bisounours-codeur
Posté le 26-09-2003 à 18:57:08  profilanswer
 

l'exemple de base
 

Code :
  1. namespace A
  2. {
  3.   class Bar
  4.   {
  5.   public:
  6.    
  7.     void method() const;
  8.   };
  9. }
  10. namespace B
  11. {
  12.   class Foo
  13.   {
  14.     void method() const;
  15.     friend void A::Bar::method() const;
  16.   };
  17. }
  18. void A::Bar::method() const
  19. {
  20.   B::Foo().method();
  21. }
  22. void B::Foo::method() const
  23. {}
  24. int main()
  25. {
  26.   A::Bar().method();
  27. }


 
passe chez toi ?

n°524228
Joel F
Real men use unique_ptr
Posté le 26-09-2003 à 19:00:17  profilanswer
 

Bon gcc 3.3.1 compile l'exemple de taz sans broncher ...
 
pe que avec un chti peu plus de code ... on verrait mieux :D

n°524229
Evadream -​jbd-
Posté le 26-09-2003 à 19:04:11  profilanswer
 

Joel F a écrit :

=> utilise gcc 3.3.1 le 3.2 est une usine a ICE.
 
=> a tu proteger tes .h apr des diretcive d'inclusions ??
 

Code :
  1. // debut du .h
  2. #ifndef _MONFICHIER_H_
  3. #define _MONFICHIER_H_
  4. // mon code
  5. #endif   /* j'ai remplacé ton #define par un #endif ;)




 
Oui, tous mes h sont protégés de cette facon ! Merci pour la recommandation du compilo. Comme je suis un peu pressé, je posterai plus de code demain (mais y'a pas grand chose). Je ne l'ai pas fait ici car j'ai pensé que le problème ne pouvait pas provenir d'autre part.  
 
Taz > un grand merci pour ton exemple de base, je verrais tout ca dès que je rentre !
 
Merci à vous deux, à demain.


Message édité par Evadream -jbd- le 26-09-2003 à 19:04:43
n°524230
Evadream -​jbd-
Posté le 26-09-2003 à 19:06:31  profilanswer
 

Taz > J'ai pas résisité et j'ai compilé ton exemple de base, pas de soucis ! Je verrais donc tout ca demain !
 
@+

mood
Publicité
Posté le 26-09-2003 à 19:06:31  profilanswer
 

n°524232
Taz
bisounours-codeur
Posté le 26-09-2003 à 19:08:07  profilanswer
 

remarque : les gardiens d'inclusion, c'est bien, encore faut-il qu'ils soient efficaces ! comprenez bien que vous n'êtes ni le premier, ni le dernier programmeur au monde à écrire un stack.hpp  :non:  alors pour vos motifs, faites un truc bien, mélangez nom du fichier, votre nom, le nom du projet, la date de création, tout ce qui vous passe par la tête (faites vous même un petit script pour automatiser tout ça si ça vous chante).

n°524235
Joel F
Real men use unique_ptr
Posté le 26-09-2003 à 19:19:15  profilanswer
 

avec celui la je suis tranquille :
 

Code :
  1. #ifndef __FILE_FROM_PROJECT_FILENAME_H__INCLUDED__
  2. #define __FILE_FROM_PROJECT_FILENAME_H__INCLUDED__

n°524239
chrisbk
-
Posté le 26-09-2003 à 19:22:23  profilanswer
 

#pragma once  
 
[:aloy]

n°524243
Joel F
Real men use unique_ptr
Posté le 26-09-2003 à 19:26:35  profilanswer
 

ca c du pure visual, je pense pas que gcc le supporte :o

n°524246
chrisbk
-
Posté le 26-09-2003 à 19:28:34  profilanswer
 

y devrait, ca resoud tous vos pb de nommage :O
 
 
(au fait, ca t'interessera pe, visu permet de faire du 3dnow & cie direct en C)

n°524255
schnapsman​n
Zaford Beeblefect
Posté le 26-09-2003 à 19:35:57  profilanswer
 

Joel F a écrit :

ca c du pure visual, je pense pas que gcc le supporte :o


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11569


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
n°524308
Evadream -​jbd-
Posté le 26-09-2003 à 20:52:16  profilanswer
 

Taz a écrit :

l'exemple de base
[...]


 
Je suis chez des amis et je passais par là ;)
Je voulais juste savoir si l'utilisation des namespace était LA marche à suivre pour utiliser des classes friends. Je pose cette question car dans toutes les choses que j'ai pu lire, je n'ai pas vu d'allusion à cela pour leur utilisation.
 
Merci !
 

n°524316
Taz
bisounours-codeur
Posté le 26-09-2003 à 21:11:49  profilanswer
 

non, ce sont deux choses distinctes. de toutes façons, tu est toujours dans namespace que tu nommes ou pas (anomyme ou global).

n°524321
Evadream -​jbd-
Posté le 26-09-2003 à 21:21:19  profilanswer
 

Ok, merci pour la réponse. Cependant, j'ai un peu de mal à faire le lien avec mon problème de portée puisque tu me dis que ce sont des problèmes distincts.  
 

n°524323
Taz
bisounours-codeur
Posté le 26-09-2003 à 21:24:08  profilanswer
 

franchement, on a besoin de vrai code

n°524341
Joel F
Real men use unique_ptr
Posté le 26-09-2003 à 22:18:54  profilanswer
 

chrisbk a écrit :


(au fait, ca t'interessera pe, visu permet de faire du 3dnow & cie direct en C)


 
du SSE 2 ???? je crois pas :D

n°524342
chrisbk
-
Posté le 26-09-2003 à 22:21:27  profilanswer
 

Joel F a écrit :


 
du SSE 2 ???? je crois pas :D


 
ben tu devrais [:spamafote]
ca s'apelle les intrinsics, fais une recherche MSDN....
 
par contre je t'explique pas l'esthetisme de la chose [:huit]


Message édité par chrisbk le 26-09-2003 à 22:21:49
n°524343
Joel F
Real men use unique_ptr
Posté le 26-09-2003 à 22:23:14  profilanswer
 

ah ... alors .... ca me permettrait d'etendre E.V.E. sur Pentium  :sol:

n°524365
Evadream -​jbd-
Posté le 26-09-2003 à 23:25:47  profilanswer
 

Taz a écrit :

franchement, on a besoin de vrai code


 
Ok, je comprends ! Je vous poste ca dès que possible !  
Encore merci pour les réponses !

n°524516
Evadream -​jbd-
Posté le 27-09-2003 à 13:20:38  profilanswer
 

Rebonjour tout le monde ! Après une bonne nuit de sommeil, je vous poste les parties de mon code qui me semblent intéressantes pour venir à bout de mon incompréhension. Mon "projet" s'articule autour de 5 fichiers (6 avec le makefile) : le couple cpp/h de la classe CLine, le couple cpp/h de la classe CSOFT_scene, et un main.cpp. Je poste les parties qui pourraient poser problème.
 
Classe CLine : CLine.h
 

Code :
  1. #ifndef _CLINE_H_26092003
  2. #define _CLINE_H_26092003
  3. #include <iostream>
  4. #include "CSOFT_scene.h"
  5. #include <SDL/SDL.h>
  6. class CLine {
  7. public:
  8.  CLine(int ix=0, int iy=0, int idx=0, int idy=0) : x1(ix), y1(iy), x2(idx), y2(idy) { }
  9.  void DrawLine(CSOFT_scene*) ; /* ligne 14 : erreur à la compilation */
  10. private:
  11.            int x1;
  12.         int y1;
  13.  int x2;
  14.  int y2;
  15. };
  16. #endif


 
Classe CLine : CLine.cpp (parties intéressantes)
 
Il n'y a que ma fonction putpixel, ds laquelle je fais appelle à une CSOFT_scene de la facon qui suit, le reste étant un simple algorithme de tracage de ligne :
 

Code :
  1. #include <SDL/SDL.h>
  2. #include "CLine.h"
  3. void CLine::DrawLine(CSOFT_scene *scene)
  4. {
  5. /* ..... */
  6. scene->putpixel(x,y,255,255,255);
  7. /* ..... */
  8. }


 
Classe CSOFT_scene : CSOFT_scene.h
 

Code :
  1. #ifndef _CSOFT_scene_26092003
  2. #define _CSOFT_scene_26092003
  3. #include <iostream>
  4. #include <string.h> /* manipulation des char* nécessaire pour void SetWindowName(const char*) */
  5. #include <SDL/SDL.h>
  6. #include "CLine.h"
  7. class CSOFT_scene {
  8.     friend class CLine ;
  9. public:
  10.  CSOFT_scene();
  11.  void CreateWindow();
  12.  void SetupPixelFormat();
  13.  void Init();
  14.  void HandleKeyPressEvent(const SDL_keysym*);
  15.  void MainLoop();
  16.  void putpixel(const int x, const int y, const Uint8 R, const Uint8 G,  const Uint8 B) ;
  17.  void Slock() ;
  18.  void Sulock() ;
  19.  void RenderScene();
  20.  void ToggleFullScreen();
  21.  void Quit(const int);
  22.  void CalculateFrameRate();
  23.  int Getheight() const;
  24.  int Getwidth() const;
  25.  int Getdepth() const;
  26.  char* GetWindowName() const;
  27.  void Setheight(const int);
  28.  void Setwidth(const int);
  29.  void Setdepth(const int);
  30.  void SetWindowName(const char*);
  31. private:
  32.  SDL_Surface * screen;
  33.  int VideoFlags;
  34.  int height;
  35.  int width;
  36.  int depth;
  37.  char* WindowName;
  38. };
  39. #endif


 
Classe CSOFT_scene : CSOFT_scene.cpp (parties intéressantes)
 
Je ne vois pas de choses qui pourraient nous intéresser ici

Code :


 
Le main : main.cpp
 

Code :
  1. #include <iostream>
  2. #include <SDL/SDL.h>
  3. #include "CLine.h"
  4. #include "CSOFT_scene.h"
  5. int main(int argc, char* argv[])
  6. {
  7. CSOFT_scene* scene = new CSOFT_scene ;
  8. scene->Init() ;
  9. scene->SetupPixelFormat() ;
  10. scene->Setwidth(640) ;
  11. scene->Setheight(480) ;
  12. scene->Setdepth(32) ;
  13. scene->SetWindowName("SDL Software Scene" );
  14. scene->CreateWindow() ;
  15. getchar();
  16. delete scene ;
  17. }


 
 
Makefile :


CC=g++
SDL = -lSDL
CFLAGS = -Wall -pedantic
CMATH = -lm
CDEBUT = -g
COPT = -O3
CPROG = resultat
 
 
std: main.o CLine.o CSOFT_scene.o
 $(CC) $(SDL) $(CFLAGS) $(CMATH) main.o CLine.o CSOFT_scene.o -o $(CPROG)
 
main.o: main.cpp
 $(CC) $(CFLAGS) -c main.cpp -o main.o
 
CLine.o: CLine.cpp
 $(CC) $(CFLAGS) -c CLine.cpp -o CLine.o
 
CSOFT_scene.o: CSOFT_scene.cpp
 $(CC) $(CFLAGS) -c CSOFT_scene.cpp -o CSOFT_scene.o
 
 
clean:
 rm -f resultat *.o
 
 


 
Résultat de la compilation :


g++ -Wall -pedantic  -c main.cpp -o main.o
g++ -Wall -pedantic  -c CLine.cpp -o CLine.o
g++ -Wall -pedantic  -c CSOFT_scene.cpp -o CSOFT_scene.o
In file included from CSOFT_scene.h:7,
                 from CSOFT_scene.cpp:3:
CLine.h:14: `CSOFT_scene' was not declared in this scope
CLine.h:14: syntax error before `)' token
make: *** [CSOFT_scene.o] Error 1


 
 
Voilà voilà :) Merci à vous !


Message édité par Evadream -jbd- le 27-09-2003 à 20:32:15
n°524521
Joel F
Real men use unique_ptr
Posté le 27-09-2003 à 13:42:28  profilanswer
 

Dans CLine.hpp, retire le  
 

Code :
  1. #include "CSOFT_scene.h"


 
utilise a la place des forward declaration :
 

Code :
  1. class CSOFT_scene;
  2. class CLine
  3. {
  4. ....
  5. };

n°524523
Taz
bisounours-codeur
Posté le 27-09-2003 à 13:43:43  profilanswer
 

on a toujours pas le fichier que tu compiles : mais tout ça semble être une inclusion circulaire mal foutue ou finalement il te manque la déclaration dans l'ordre. amuse toi avec g++ -E machin.cpp | less et regarde l'imbroglio


Message édité par Taz le 27-09-2003 à 13:47:10
n°524524
Taz
bisounours-codeur
Posté le 27-09-2003 à 13:47:45  profilanswer
 

Joel F a écrit :


utilise a la place des forward declaration

correct

n°524536
Joel F
Real men use unique_ptr
Posté le 27-09-2003 à 14:11:25  profilanswer
 


 
Vous ètes le maillon fort  [:spyer]

n°524555
Evadream -​jbd-
Posté le 27-09-2003 à 14:50:23  profilanswer
 

Taz a écrit :

on a toujours pas le fichier que tu compiles


 
Ca fait un peu boulay, désolé [:ddr555]. Tu parles de CSOFT_scene.cpp ? Je ne l'avais pas mis délibérement parce que je pensais pas que le problème pouvait provenir de là. Je le poste si je n'ai pas réussi à résoudre le problème avec tous les élements que vous m'avez donné.
 

Taz a écrit :

mais tout ça semble être une inclusion circulaire mal foutue ou finalement il te manque la déclaration dans l'ordre. amuse toi avec g++ -E machin.cpp | less et regarde l'imbroglio


 
Ok très bien ! Merci pour le conseil !
 

Joel F a écrit :

Dans CLine.hpp, retire le
 
[...]  
 


 
Ok, je fais ca dès que j'ai accès à mon programme :) Merci !


Message édité par Evadream -jbd- le 27-09-2003 à 14:53:10
n°524744
Evadream -​jbd-
Posté le 27-09-2003 à 20:09:24  profilanswer
 

EDIT : Etourderie ds le makefile. Le g++ -o main.o ... s'est transformé en g++ main.o -o :) Ca va mieux !
 
Hello !
 
Donc, les forward déclarations m'ont permis de mettre fin à mon soucis de compilation (yeahhh, merci !). Par contre, je ne peux apparement pas me passer du
 

Code :
  1. #include "CSOFT_scene.h"


 
dans CLine.h à cause de (je pense)
 

Code :
  1. void DrawLine(CSOFT_scene*) ;


 
L'erreur de compilation, si j'utilise ici une forward déclaration de CSOFT_scene, est alors la suivante :
 


CLine.cpp: In member function `void CLine::DrawLine(CSOFT_scene*)':
CLine.cpp:38: invalid use of undefined type `struct CSOFT_scene'
CLine.h:6: forward declaration of `struct CSOFT_scene'
CLine.cpp:52: invalid use of undefined type `struct CSOFT_scene'
CLine.h:6: forward declaration of `struct CSOFT_scene'
make: *** [CLine.o] Error 1


 
Ca fonctionne avec le #include, donc je n'ai pas de soucis, si ce n'est que je ne comprends pas exactement pourquoi la forward déclaration fonctionne pour CLine et non pour CSOFT_scene.
 
En tout cas, un grand merci à tous pour votre aide et votre patience !
 
@+


Message édité par Evadream -jbd- le 27-09-2003 à 20:33:21
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [C++] Problèmes à la compilation avec des fonctions amies

 

Sujets relatifs
[jbuilder] problemes de double bufferingCompilation JAVA depuis un programme JAVA
problèmes css diversPasser mon site en XHTML + CSS : Petits problèmes
[java]erreur lors de compilation sous Visual Studio.netKylix 3 Open C++ : Problème de compilation, voilà le log
Erreur de compilation... [RESOLU][VBA-exel]Erreur de compilation Sub / erreur defini par l'application?
[Windows] Nomenclature des fonctions : comprendre les windowseries[VBA] (ACCESS) "erreur de compilation - attendu Then ou goto " ...
Plus de sujets relatifs à : [C++] Problèmes à la compilation avec des fonctions amies


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR