OVH Cloud OVH Cloud

héritage à partir d'un template

13 réponses
Avatar
LaFleche
Bonjour,

J'ai une classe générique A<> et je souhaite déclarer une classe B qui
hérite de l'instance A<int>.

Evidenment y'a une couille dans le potage quelque part puisque g++
m'insulte à l'édition de lien.

Je ne sais pas du tout d'où viens le problème et google n'est plus mon
ami depuis ce jour :(.


J'ai donc la classe A<> (A.h et A.cc) et la classe B (B.h et B.cc).

voici mes fichiers :

***** A.h *****
#ifndef A_h
#define A_h

template<typename T>
class A
{
public :
A();
virtual ~A();

virtual void foo();
};

#endif
****/A.h *****

***** A.cc *****
#include "A.h"

template<typename S>
A<S>::A(){}

template<typename S>
A<S>::~A(){}

template<typename S>
void A<S>::foo(){}
*****/A.cc *****


***** B.h *****
#ifndef B_h
#define B_h

#include "A.h"

class B : A<int>
{
public :
B();
virtual ~B();

virtual void foo();
};

#endif
*****/B.h *****

***** B.cc *****

#include "B.h"

B::B(){}
B::~B(){}

void B::foo(){}
*****/B.cc *****

La compilation séparé ne produit pas d'erreur, c'est à l'édition de lien
qu'il y à un problème.


Le message de gcc :
g++ -Wall -c Main.cc
g++ -Wall -c A.cc
g++ -Wall -c B.cc
g++ Main.o A.o B.o -o run
B.o(.text+0xd): In function `B::B[not-in-charge]()':
: undefined reference to `A<int>::A[not-in-charge]()'
B.o(.text+0x2d): In function `B::B[in-charge]()':
: undefined reference to `A<int>::A[not-in-charge]()'
B.o(.text+0x56): In function `B::~B [not-in-charge]()':
: undefined reference to `A<int>::~A [not-in-charge]()'
B.o(.text+0x90): In function `B::~B [in-charge]()':
: undefined reference to `A<int>::~A [not-in-charge]()'
B.o(.text+0xca): In function `B::~B [in-charge deleting]()':
: undefined reference to `A<int>::~A [not-in-charge]()'
collect2: ld returned 1 exit status


Remarquez que la methode foo(), redéfinie dans B, ne semble pas lui
poser de problème, ce sont les destructeur et les constructeurs qui le
chagrine.

Merci de votre aide.

10 réponses

1 2
Avatar
Twxs
LaFleche wrote:
Bonjour,

J'ai une classe générique A<> et je souhaite déclarer une classe B qui
hérite de l'instance A<int>.

Evidenment y'a une couille dans le potage quelque part puisque g++
m'insulte à l'édition de lien.

Je ne sais pas du tout d'où viens le problème et google n'est plus mon
ami depuis ce jour :(.


J'ai donc la classe A<> (A.h et A.cc) et la classe B (B.h et B.cc).


La compilation séparé ne produit pas d'erreur, c'est à l'édition de lien
qu'il y à un problème.




fait un #include "A.cc" a la fin de A.h le compilo a besoin du code pour
les templates. certain renomme le .cc en .inc

Twxs

Avatar
LaFleche
fait un #include "A.cc" a la fin de A.h le compilo a besoin du code pour
les templates. certain renomme le .cc en .inc

Twxs


Merci Twxs, je viens de le faire et depuis A.cc ne se compile plus.
Je n'y comprend pas grand chose et les messages de g++ ne m'aident pas
vraiment.

A.cc:4: error: redefinition of `A<T>::A()'
A.cc:4: error: `A<T>::A()' previously declared here
A.cc:4: error: no `A<T>::A()' member function declared in class `A<T>'
A.cc:7: error: redefinition of `A<T>::~A()'
A.cc:7: error: `virtual A<T>::~A()' previously declared here
A.cc:7: error: no `A<T>::~A()' member function declared in class `A<T>'
A.cc:10: error: redefinition of `void A<T>::foo()'
A.cc:10: error: `virtual void A<T>::foo()' previously declared here
A.cc:10: error: no `void A<T>::foo()' member function declared in class
`A<T>'
make: *** [A.o] Erreur 1

Avatar
Arnaud Debaene
LaFleche wrote:
fait un #include "A.cc" a la fin de A.h le compilo a besoin du code
pour les templates. certain renomme le .cc en .inc

Twxs


Merci Twxs, je viens de le faire et depuis A.cc ne se compile plus.
Je n'y comprend pas grand chose et les messages de g++ ne m'aident pas
vraiment.


Tu n'as pas à compiler A.cc (de la même façon que tu ne donnes pas
directment les .h au compilateur) : un template doit être entièrement
déclaré et défini dans un header (d'où l'#include du .cc à la fin du .h : en
fait on place le contenu du .cc dans le .h).

Remarque : Dans l'absolu, on peut avoir l'implémentation d'un template dans
un fichier séparé, mais ca demande le mot clé "export" qui n'est pas
supporté par gcc pour l'instant.

Arnaud


Avatar
kanze
"Arnaud Debaene" wrote in message
news:<409ab5ba$0$13069$...
LaFleche wrote:
fait un #include "A.cc" a la fin de A.h le compilo a besoin du code
pour les templates. certain renomme le .cc en .inc


Merci Twxs, je viens de le faire et depuis A.cc ne se compile plus.
Je n'y comprend pas grand chose et les messages de g++ ne m'aident
pas vraiment.


Tu n'as pas à compiler A.cc (de la même façon que tu ne donnes pas
directment les .h au compilateur) : un template doit être entièrement
déclaré et défini dans un header (d'où l'#include du .cc à la fin du
.h : en fait on place le contenu du .cc dans le .h).


Surtout, je crois, il ne doit pas faire un #include du .h dans le .cc.
(En fait, tu peux compiler le .cc avec g++, mais ça ne sert à rien.)

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
adebaene
wrote in message news:...
"Arnaud Debaene" wrote in message
news:<409ab5ba$0$13069$...
LaFleche wrote:
fait un #include "A.cc" a la fin de A.h le compilo a besoin du code
pour les templates. certain renomme le .cc en .inc


Merci Twxs, je viens de le faire et depuis A.cc ne se compile plus.
Je n'y comprend pas grand chose et les messages de g++ ne m'aident
pas vraiment.


Tu n'as pas à compiler A.cc (de la même façon que tu ne donnes pas
directment les .h au compilateur) : un template doit être entièrement
déclaré et défini dans un header (d'où l'#include du .cc à la fin du
.h : en fait on place le contenu du .cc dans le .h).



Surtout, je crois, il ne doit pas faire un #include du .h dans le .cc.
Oups, oui évidemment, je n'y ai même pas pensé!



(En fait, tu peux compiler le .cc avec g++, mais ça ne sert à rien.)
Il fait quoi de ce source? Il génère un .obj? Qu'y a-t-il dedans?


Arnaud




Avatar
LaFleche
Arnaud Debaene wrote:

Tu n'as pas à compiler A.cc (de la même façon que tu ne donnes pas
directment les .h au compilateur) : un template doit être entièrement
déclaré et défini dans un header (d'où l'#include du .cc à la fin du .h : en
fait on place le contenu du .cc dans le .h).



Merci c'était ça effectivement.

Avatar
James Kanze
(Arnaud Debaene) writes:

|> wrote in message
|> news:...
|> > "Arnaud Debaene" wrote in message
|> > news:<409ab5ba$0$13069$...
|> > > LaFleche wrote:
|> > > >> fait un #include "A.cc" a la fin de A.h le compilo a besoin
|> > > >> du code pour les templates. certain renomme le .cc en .inc

|> > > > Merci Twxs, je viens de le faire et depuis A.cc ne se compile
|> > > > plus. Je n'y comprend pas grand chose et les messages de g++
|> > > > ne m'aident pas vraiment.

|> > > Tu n'as pas à compiler A.cc (de la même façon que tu ne
|> > > donnes pas directment les .h au compilateur) : un template doit
|> > > être entièrement déclaré et défini dans un header
|> > > (d'où l'#include du .cc à la fin du .h : en fait on place
|> > > le contenu du .cc dans le .h).

|> > Surtout, je crois, il ne doit pas faire un #include du .h dans le .cc.
|> Oups, oui évidemment, je n'y ai même pas pensé!

|> > (En fait, tu peux compiler le .cc avec g++, mais ça ne sert
|> > à rien.)
|> Il fait quoi de ce source? Il génère un .obj? Qu'y a-t-il
|> dedans?

Il en génère un fichier objet, oui. Qui est effectivement vide.
(Il se peut qu'il contient des en-têtes, avec de l'information du
genre « longueuer du segment texte : 0 ».)

Mais ce .cc est bien une source C++, parfaitement légale, et on doit
pouvoir le compiler. Tu compiles bien les fichiers source avec un seul
include, n'est-ce pas, pour s'assurer que l'en-tête contient tout ce
qu'il doit contenir ?

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
drkm
writes:

Tu n'as pas à compiler A.cc (de la même façon que tu ne donnes pas
directment les .h au compilateur) : un template doit être entièrement
déclaré et défini dans un header (d'où l'#include du .cc à la fin du
.h : en fait on place le contenu du .cc dans le .h).


Surtout, je crois, il ne doit pas faire un #include du .h dans le .cc.
(En fait, tu peux compiler le .cc avec g++, mais ça ne sert à rien.)


Je n'arrive pas à voir le problème si on utilise les include guards
qui vont bien. Y a-t-il réellement une contre-indication spécifique ?

--drkm


Avatar
James Kanze
drkm writes:

|> writes:

|> > > Tu n'as pas à compiler A.cc (de la même façon que tu ne
|> > > donnes pas directment les .h au compilateur) : un template doit
|> > > être entièrement déclaré et défini dans un header
|> > > (d'où l'#include du .cc à la fin du .h : en fait on place
|> > > le contenu du .cc dans le .h).

|> > Surtout, je crois, il ne doit pas faire un #include du .h dans le
|> > .cc. (En fait, tu peux compiler le .cc avec g++, mais ça ne
|> > sert à rien.)

|> Je n'arrive pas à voir le problème si on utilise les include
|> guards qui vont bien. Y a-t-il réellement une contre-indication
|> spécifique ?

C'est vrai qu'avec l'utilisation des gardes classiques, il ne doit pas y
avoir de problème. Mais bon, le poster original n'en avait pas. Et je
n'en ai jamais vu non plus dans le code que je maintiens.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
drkm
James Kanze writes:

drkm writes:


[...]

|> Je n'arrive pas à voir le problème si on utilise les include
|> guards qui vont bien. Y a-t-il réellement une contre-indication
|> spécifique ?

C'est vrai qu'avec l'utilisation des gardes classiques, il ne doit pas y
avoir de problème. Mais bon, le poster original n'en avait pas. Et je
n'en ai jamais vu non plus dans le code que je maintiens.


Tiens. Je pensais que ce faisait partie du BABa. J'ai eu un doute,
et j'ai vérifié dans la gabi-lib, tu les utilises bien, Serge
Smeesters aussi, je m'en souviens ; je n'ai pas vu de code personnel
d'autres participants de fclc++, je pense. Il me semble que j'en ai
toujours vu dans le code libre que j'ai pris le temps de regarder.

J'avoue que cela m'étonne, vu toutes les contraintes que tu dis
devoir respecter dans ton code professionnel. Y a-t-il des raisons
puor ne pas employer d'include guards ?

--drkm

1 2