-
Error lnk 2019
Bonjour,
j'ai un problème avec Visual C++ 2005 Express editionlors de la génération de mon projet.
Le message d'erreur est le suivant :
error LNK2019: symbole externe non résolu "class std::basic_ofstream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ofstream<char,struct std::char_traits<char> > &,class Matrix<class Complex> &)" (??6@YAAAV?$basic_ofstream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Matrix@VComplex@@@@@Z) référencé dans la fonction _main
Si quelqu'un pouvait m'aider, je ne comprends pas du tout d'ou cela peut venir, mon code a l'air bon.
Merci d'avance.
-
Ca pourrait aider de voir le code.
Tu as jeté un oeil à la FAQ C++ section templates ?
-
Salut, voici le code que j'ai : (Désolé j'ai copié le code entier, je peux les mettre en pieces jointes sinon car c'est un peu décourageant tout ça...)
//fichier main.cpp
#include <iostream> // for cin and cout
#include <fstream> // for file input and output
#include "matrix.h" // file containing the matrix class
#include "complex.h"
int main()
{
Matrix<Complex> m1, m2 ;
std::cin >> m1; // input matrix m1 from keyboard (as user wants)
std::ifstream ifs("complex_matrix.dat");
std::ofstream ofs("result.dat") ;
ifs >> m2; // read matrix m2 from the file matrix.dat
Matrix<Complex> m3;
m3 = m1*m2; // multiply them together, store in m3
std::cout << m3; // output m3 to the screen
ofs << m3; // output m3 to file result.dat
return 0;
}
//fichier complex.cpp
#include "complex.h"
Complex::Complex() : re(0.0), im(0.0)
{
}
Complex::Complex(double Re, double Im):re(Re), im(Im)
{
}
Complex::Complex(const Complex& c): re(c.re), im(c.im)
{
}
double Complex::getReal() const
{
return re;
}
double Complex::getImg() const
{
return im;
}
Complex Complex::Inverse() const
{
Complex temp;
temp.re=re/(re*re+im*im);
temp.im=-im/(re*re+im*im);
return temp;
}
Complex& Complex::operator=(const Complex& c)
{
re=c.re;
im=c.im;
return *this;
}
Complex operator+(const Complex& c1, const Complex& c2)
{
Complex temp;
temp.re=c1.re+c2.re;
temp.im=c1.im+c2.im;
return temp;
}
Complex operator-(const Complex& c1, const Complex& c2)
{
Complex temp;
temp.re=c1.re-c2.re;
temp.im=c1.im-c2.im;
return temp;
}
Complex operator*(const Complex& c1, const Complex& c2)
{
Complex temp;
temp.re=c1.re*c2.re-c1.im*c2.im;
temp.im=c1.im*c2.re+c1.re*c2.im;
return temp;
}
Complex operator/(const Complex& c1, const Complex& c2)
{
Complex temp;
temp=c1.Inverse();
return (c2*temp);
}
Complex Complex::operator-()
{
Complex temp(-re, -im);
return temp;
}
bool operator==(const Complex& c1, const Complex& c2)
{
if (c1.re==c2.re && c1.im==c2.im)
{
return true;
}
else return false;
}
bool operator!=(const Complex& c1, const Complex& c2)
{
if (c1.re!=c2.re || c1.im!=c2.im)
{
return true;
}
else return false;
}
std::istream& operator>>(std::istream& is, Complex& c)
{
std::cout<< "input the real part\n";
is>>c.re;
std::cout<< "Input the imaginary part\n";
is>>c.im;
return is;
}
std::ostream& operator<<(std::ostream& os, Complex& c)
{
os<< "the Real part is "<< c.re <<"\n";
os<< " the imaginary part is " <<c.im <<"\n";
return os;
}
//fichier complex.h
//#include "vector.h"
//#include "matrix.h"
#include <iostream>
#include <fstream>
class Complex
{
private:
double re, im;
public:
Complex();
Complex(double Re, double Im);
Complex (const Complex& c);
double getReal() const;
double getImg() const;
Complex Inverse() const;
Complex& operator=(const Complex& c);
friend Complex operator+(const Complex& c1, const Complex& c2);
friend Complex operator-(const Complex& c1, const Complex& c2);
friend Complex operator*(const Complex& c1, const Complex& c2);
friend Complex operator/(const Complex& c1, const Complex& c2);
Complex operator-();
friend bool operator==(const Complex& c1, const Complex& c2);
friend bool operator!=(const Complex& c1, const Complex& c2);
friend std::istream& operator>>(std::istream& is, Complex& c);
friend std::ostream& operator<<(std::ostream& os, Complex& c);
};
//Fichier vector.h
#include <iostream>
#include <fstream>
template <class T>
class Vector
{
private:
int num; // Number of elements
double* pdata; // Pointer to the data
void Init(int Num); // private function since user should not call it
// only for the member functions to call
public:
Vector(); // default constructor
Vector(int Num); // alternate constructor
Vector(const Vector<T>& v); // copy constructor
~Vector(); // destructor
int GetNum() const; // access function
Vector<T>& operator= (const Vector<T>& v); // overloaded assignment operator
T& operator[] (int i) const; // overloaded array access operator
friend std::istream& operator>>(std::istream& is, Vector<T>& v);// keyboard input
friend std::ostream& operator<<(std::ostream& os, Vector<T>& v);// screen output
friend std::ifstream& operator>>(std::ifstream& ifs, Vector<T>& v);// file input
friend std::ofstream& operator<<(std::ofstream& ofs, Vector<T>& v);// file output
};
// default constructor
template <class T>
Vector<T>::Vector() : num(0), pdata(0) {}
// initialise data, called by the constructors
template <class T>
void Vector<T>::Init(int Num)
{
num = Num;
if (num <= 0)
pdata = 0; // Object construction failed!
else
pdata = new double[num]; // Allocate memory for vector
}
// alternate constructor
template <class T>
Vector<T>::Vector(int Num)
{
Init(Num);
}
// copy constructor
template <class T>
Vector<T>::Vector(const Vector& copy)
{
Init(copy.GetNum()); // allocate the memory
// copy the data members
if (pdata) for (int i=0; i<num; i++) pdata[i]=copy.pdata[i];
}
// destructor
template <class T>
Vector<T>::~Vector()
{
delete [] pdata; // free the dynamic memory
}
// assignment operator
template <class T>
Vector<T>& Vector<T>::operator=(const Vector<T>& copy)
{
if (this == ©) return *this; // Can't copy self to self (that is v = v
// in main is dealt with)
delete [] pdata; // delete existing memory
Init(copy.GetNum()); // create new memory then copy data
if (pdata) for (int i=0; i<copy.GetNum(); i++) pdata[i] = copy.pdata[i];
return *this;
}
// array access operator
template <class T>
T& Vector<T>::operator[](int i) const
{
if (i < 0)
i = 0; // Range error causes index to equal 0
// should really throw an exception
return pdata[i];
}
// return the size of the vector
template <class T>
int Vector<T>::GetNum() const
{
return num;
}
// keyboard input
template <class T>
std::istream& operator>>(std::istream& is, Vector<T>& v) {
int Num;
std::cout << "input the size for the vector\n";
is >> Num;
// create a temporary Vector object of correct size
Vector temp(Num);
// input the elements
std::cout << "input the vector elements\n";
for (int i=0; i<Num; i++) is >> temp[i];
// copy temp into v
v = temp;
// return the stream object
return is;
}
// file input
template <class T>
std::ifstream& operator>>(std::ifstream& ifs, Vector<T>& v)
{
int Num;
// read size from the file
ifs >> Num;
// create a temporary Vector object of correct size
Vector temp(Num);
// input the values
for (int i=0; i<Num; i++) ifs >> temp[i];
// copy temp into v
v = temp;
// return the file stream object
return ifs;
}
// screen output
template <class T>
std::ostream& operator<<(std::ostream& os, Vector<T>& v)
{
if (v.pdata) {
os << "The vector elements are\n";
for (int i=0; i<v.GetNum(); i++) os << v[i] << "\n";
}
return os;
}
// file output
template <class T>
std::ofstream& operator<<(std::ofstream& ofs, Vector<T>& v)
{
if (v.pdata) {
ofs << "The vector elements are\n";
for (int i=0; i<v.GetNum(); i++) ofs << v[i] << "\n";
}
return ofs;
}
//Fichier matrix.h
#include "vector.h"
#include <iostream>
#include <fstream>
template<class T>
class Matrix
{
private:
Vector<T> v; // Vector used to store the matrix elements
int nrows; // number of rows of the matrix
int ncols; // number of columns of the matrix
public:
Matrix(); // default constructor, uses default constructor for v
Matrix(int Nrows, int Ncols); // alternate constructor
T& operator() (int i, int j) const; // function call overload (-,-)
friend Matrix<T> operator*(const Matrix<T>& m1, const Matrix<T>& m2);// overload * for matrix multiplication
friend std::istream& operator>>(std::istream& is, Matrix<T>& m);// keyboard input
friend std::ostream& operator<<(std::ostream& os, Matrix<T>& m);// screen output
friend std::ifstream& operator>>(std::ifstream& ifs, Matrix<T>& m);// file input
friend std::ofstream& operator<<(std::ofstream& ofs, Matrix<T>& m);// file output
};
template<class T>
Matrix<T>::Matrix() : v(0), nrows(0), ncols(0) {}
// alternate constructor
template<class T>
Matrix<T>::Matrix(int Nrows, int Ncols) : v(Nrows*Ncols)
{
nrows = Nrows;
ncols = Ncols;
}
// function call overload (-,-)
template<class T>
T& Matrix<T>::operator() (int i, int j) const
{
return v[i*ncols+j];
}
// overload * for matrix multiplication
template<class T>
Matrix<T> operator*(const Matrix<T>& m1, const Matrix<T>& m2)
{
Matrix<T> m(m1.nrows,m2.ncols);
if(m1.ncols==m2.nrows)
{
for(int i=0 ; i<m1.nrows ; i++)
for(int j=0 ; j<m1.ncols ; j++)
{
m(i,j) = T();
for(int k=0 ; k<m2.nrows ; k++)
m(i,j) = m(i,j) + (m1(i,k)*m2(k,j));
}
return m;
}
else//problem of the size of the matrix
{
std::cout << "The multiplication is impossible,there a problem about the dimension of the two matrix \n";
getchar();
getchar();
return m;
}
}
// keyboard input
template<class T>
std::istream& operator>>(std::istream& is, Matrix<T>& m)
{
int Nrows, Ncols;
// input the size of the matrix
std::cout << "input num of rows and columns\n";
is >> Nrows >> Ncols;
// create a temporary matrix of the correct size
Matrix<T> temp(Nrows, Ncols);
std::cout << "input the matrix elements\n";
for (int i=0; i<Nrows; i++)
for (int j=0 ; j<Ncols; j++)
{
std::cout << i+1 << j+1 << " : ";
is >> temp(i,j);
}
// copy temp to m
m = temp;
return is;
}
// screen output
template<class T>
std::ostream& operator<<(std::ostream& os, Matrix<T>& m)
{
if(m.v.GetNum())
{
os << "The matrix elements are :\n";
for(int i=0 ; i<m.nrows ; i++)
{
for(int j=0 ; j<m.ncols ; j++)
os << m(i,j) << " ";
os << "\n";
}
}
return os;
}
// file input
template<class T>
std::ifstream& operator>>(std::ifstream& ifs, Matrix<T>& m)
{
int Nrows, Ncols;
//read size from the file
ifs >> Nrows >> Ncols;
//create a temporary Matrix object of correct size
Matrix<T> temp(Nrows, Ncols);
//input the values
for(int i=0; i<Nrows; i++)
for(int j=0; j<Ncols; j++)
ifs >> temp(i,j);
//copy temp to m
m = temp;
//return the file stream object
return ifs;
}
// file output
template<class T>
std::ofstream& operator<<(std::ofstream& ofs, Matrix<T>& m)
{
if(m.v.GetNum())
{
ofs << "The matrix elements are :\n";
for(int i=0 ; i<m.nrows ; i++)
{
for(int j=0 ; j<m.ncols ; j++)
ofs << m(i,j) << " ";
ofs << "\n";
}
}
return ofs;
}
-
Pb LNK2019
C'est bon c'est résolu, je me suis inspiré d'une de tes réponses que tu as données dans un autre forum.
C'etait un problème avec les fonction "friend".
J'ai suivi la même démarche.
Merci beaucoup