OVH Cloud OVH Cloud

Problème avec iostream

11 réponses
Avatar
Etienne Rousee
Bonjour,

Quelqu'un connaît il l'erreur suivante (VC++ 6.0, Projet console W32 sans
MFC, erreur au link) :

TestPoly.obj : error LNK2001: unresolved external symbol "class
std::basic_ostream<char,struct std::char_traits<char> > & __cdecl
operator<<(class std::basic_ostream<char,struct std::char_traits<char> >
&,class Rationnel &)"
(??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVRationnel@@@
Z)

J'ai impléménté une classe Rationnel, et j'ai voulu surcharger le chevron
sortant:

ostream& operator<<(ostream&, Rationnel &);

C'est en prototype, en amie dans la classe, et codé.
Evidemment, tout fonctionne quand j'enlève les affichages.
J'ai un Rationnel.h, un Rationnel.cpp, un principal, et
quelques autres fichiers.

Je subodore qu'il y a un rapport avec la différence entre
<iostream> et <iostream.h>, mais ça m'échappe.

Etienne

10 réponses

1 2
Avatar
Loïc Joly
Etienne Rousee wrote:
Bonjour,

Quelqu'un connaît il l'erreur suivante (VC++ 6.0, Projet console W32 sans
MFC, erreur au link) :


Sans avoir un peu plus de code, difficile de t'aider...

--
Loïc

Avatar
kanze
Etienne Rousee wrote:

Quelqu'un connaît il l'erreur suivante (VC++ 6.0, Projet
console W32 sans MFC, erreur au link) :

TestPoly.obj : error LNK2001: unresolved external symbol "class
std::basic_ostream<char,struct std::char_traits<char> > & __cdecl
operator<<(class std::basic_ostream<char,struct
std::char_traits<char> >

&,class Rationnel &)"

(???$?$@std@@@std@@@@@

Z)

J'ai impléménté une classe Rationnel, et j'ai voulu surcharger
le chevron sortant:

ostream& operator<<(ostream&, Rationnel &);

C'est en prototype, en amie dans la classe, et codé.
Evidemment, tout fonctionne quand j'enlève les affichages.
J'ai un Rationnel.h, un Rationnel.cpp, un principal, et
quelques autres fichiers.

Je subodore qu'il y a un rapport avec la différence entre
<iostream> et <iostream.h>, mais ça m'échappe.


C'est un peu jouer aux devinettes avec le peu d'informations
dont on dispose, mais est-ce que tu n'aurais pas déclarer la
fonction amie avec std::ostream (soit en écrivant std::ostream
directement, soit à cause d'un using quelque part) et que tu
l'as défini avec un simple ostream ? Ou l'avoir défini inline,
mais avoir mis la définition dans un .cpp ?

--
James Kanze GABI Software http://www.gabi-soft.fr
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
Etienne Rousee
"Etienne Rousee" a écrit ...

Bon, je n'ai pas eu trop de temps cette semaine,
mais voilà, en enlevant plein de choses, le code
suivant compile mais le link plante.
Il n'y a plus d'erreur si j'enlève les cout.

si quelqu'un a une idée ?

Il y a 3 fichiers:

/***** Fichier Point.h **********/

template <class T> class Point;

template <class T> ostream& operator<<(ostream&, Point<T> &);

template <class T> class Point
{
friend ostream& operator<<(ostream&, Point<T> &);

public:
Point (T x = 0, T y = 0) : _x(x), _y(y) { }

void SetX(T x = 0) { _x = x; }
void SetY(T y = 0) { _y = y; }

T GetX(void) { return _x; }
T GetY(void) { return _y; }

protected:
T _x,_y;
};

/******** Fichier Point.cpp **********/

#include <iostream>

using namespace std;

#include "Point.h"

template <class T> ostream& operator<<(ostream &out,Point<T> &P)
{
out << "X = " << P.GetX() << " Y = " << P.GetY();

return out;
}

/******** Fichier TestPoint.cpp **********/

#include <iostream>

using namespace std;

#include "point.h"

void TestPoint(void);

/***************************************************************************
*/

void TestPoint(void)
{
Point<int> P1(3,4);
Point<double> P2(3.14,2.718);

cout << "Point P1 : " << P1 << endl;
cout << "Point P2 : " << P2 << endl;
}

/***************************************************************************
*/

int main(void)
{
TestPoint();

return 0;
}
Avatar
drkm
"Etienne Rousee" writes:

le code suivant compile


Comment compiles-tu ?

mais le link plante.


Quelle est l'erreur ?

--drkm

Avatar
Jean-Sebastien Mouret
"Etienne Rousee" writes:

"Etienne Rousee" a écrit ...

Bon, je n'ai pas eu trop de temps cette semaine,
mais voilà, en enlevant plein de choses, le code
suivant compile mais le link plante.
Il n'y a plus d'erreur si j'enlève les cout.

si quelqu'un a une idée ?


bouge la definition de l'operator<< template dans le header,
ca devrait etre bon.


--
js

Avatar
drkm
"Etienne Rousee" writes:

"Jean-Sebastien Mouret" a écrit ...

bouge la definition de l'operator<< template dans le header,
ca devrait etre bon.


Ça marche, mais j'aimerais comprendre pourquoi.


Une recherche dans les archives avec « en-tête template » devrait
t'en dire plus. Recherche éventuellement aussi après « export ».

En gros, lorsque tu implémentes un modèle, tu dois utiliser
« export » ou le fournir à tous les clients (en clair, l'inclure dans
l'en-tête).

--drkm


Avatar
drkm
"Etienne Rousee" writes:

"drkm" a écrit ...

Une recherche dans les archives avec « en-tête template » devrait
t'en dire plus. Recherche éventuellement aussi après « export ».


Ok, merci, j'ai compris, mais:
- le mot "export" ne semble pas être reconnu par VC++ 6.0
et d'après C.Casteyde, par aucun compilateur.


Il est en effet peut supporté. Le front end d'EDG (utilisé dans
como et icc) est je pense le seul à l'heure actuelle à le supporter.
Tu peux chercher après les retours d'expérience de Jean-Marc pour plus
d'infos.

Mais franchement, à l'heure actuelle, si tu ne connais pas
intimement « export », c'est que tu ne veux pas l'utiliser. Si tu
veux garder l'implémentation de tes modèles dans des fichiers séparés,
tu peux utiliser un fichier .tcc que tu inclus à la fin de ton
en-tête, comme il l'a été décrit plusieurs fois ici (idem pour tes
fonctions inlines).

En tout cas, je ne peux t'en dire plus, ne m'étant jamais intéressé
de près à la bête.

- j'ai compliqué un peu les choses et ajouté une classe
Rationnel pour pouvoir faire des Point<Rationnel>.
Cette classe n'est pas une classe template, et pourtant
il m'a fallu quand même mettre la définition de son
operator<< dans l'en-tête Rationnel.h, le link produisant
la même erreur quand je la mets dans Rationnel.cpp.
Pourquoi ?


Quel est la définition (surtout la déclaration) de l'opérateur ?
Quelle est la ligne de compilation ? Quelle est l'erreur de l'éditeur
de liens ?

Il ne faut pas publier le code de tout ton programme, mais il faut
quand même nous en dire un peu plus.

--drkm


Avatar
Gabriel Dos Reis
"Etienne Rousee" writes:

| Ok, merci, j'ai compris, mais:
| - le mot "export" ne semble pas être reconnu par VC++ 6.0
| et d'après C.Casteyde, par aucun compilateur.

« export » est supporté au moins par deux compilateurs, sur divers
plateformes.

Mais si tu veux un maximum de portabilité (à définir), tu peux essayer
d'arranger tes programmes autrement. Si tu débutes en programmation
avec C++, tu peux momentanément l'oublier.

-- Gaby
Avatar
Etienne Rousee
"Gabriel Dos Reis" a écrit ...
"Etienne Rousee" writes:

| Ok, merci, j'ai compris, mais:
| - le mot "export" ne semble pas être reconnu par VC++ 6.0
| et d'après C.Casteyde, par aucun compilateur.

« export » est supporté au moins par deux compilateurs, sur divers
plateformes.


Lesquels ?

Mais si tu veux un maximum de portabilité (à définir),


Je préfère.
tu peux essayer d'arranger tes programmes autrement.


C'est à dire ?

Si tu débutes en programmation


Ben non.

avec C++, tu peux momentanément l'oublier.


Non, je voudrais en savoir plus.

--

Etienne

Avatar
Gabriel Dos Reis
"Etienne Rousee" writes:

| "Gabriel Dos Reis" a écrit ...
| > "Etienne Rousee" writes:
| >
| > | Ok, merci, j'ai compris, mais:
| > | - le mot "export" ne semble pas être reconnu par VC++ 6.0
| > | et d'après C.Casteyde, par aucun compilateur.
| >
| > « export » est supporté au moins par deux compilateurs, sur divers
| > plateformes.
|
| Lesquels ?

Le compilo d'Intel (sous Linux comme sous Windows); le compilo de
Como (divsers plateforms unix et windows).

(Je ne sais pas encore ce que font SGI et HP).

|
| > Mais si tu veux un maximum de portabilité (à définir),
|
| Je préfère.
| >tu peux essayer d'arranger tes programmes autrement.
|
| C'est à dire ?

utilise le modèle d'inclusion -- inclus les définitions templates là
où nécessaire.


|
| >Si tu débutes en programmation
|
| Ben non.
|
| > avec C++, tu peux momentanément l'oublier.
|
| Non, je voudrais en savoir plus.

Dans ce cas, je te recommande le bouquin de Vandevoorde et Josuttis.

-- Gaby
1 2