I have been learning some standard OOP things like working with classes and so on. And I've got into the trouble, when code seems not to be mistaken, but compilator keeps telling you about some crappy errors. After a while I decided to ask a question there. I made some "research" earlier and tried to fix it myself, but all my attempts were unsuccessful. The problem appears when I try to use template to practise building proper classes (all is ok when I use ordinary types like int, float etc). Code looks pretty and IDE doesn't see any mistakes there, but when compilation begins some errors emerge, saying that there are unresolved external symbols.
CODE: main()
#include <iostream>
#include "Rectangle.h"
using namespace std;
void main()
{
Rectangle<int> b(0, 0, 0, 5, 10, 5, 10, 0);
cout << "Your rectangle: \n" << b << endl;
cout << "It's perimeter: " << b.perimeter() << " cm" << endl;
cout << "Area of your rectangle = " << b.area() << " cm^2" << endl;
system("pause");
}
CODE: Rectangle.h
#include <iostream>
using namespace std;
template <typename R> class Rectangle
{
public:
Rectangle(R, R, R, R, R, R, R, R);
~Rectangle();
float area();
float perimeter();
friend ostream& operator<<(ostream&, Rectangle&);
private:
R vect[4][2];
float length(R,R,R,R);
};
CODE: Rectangle.cpp
#include "Rectangle.h"
#include <iostream>
using namespace std;
template <typename R> Rectangle<R>::Rectangle(R x1,R y1,R x2,R y2,R x3,R y3,R x4,R y4)
{
vect[0][0] = x1;
vect[0][1] = y1;
vect[1][0] = x2;
vect[1][1] = y2;
vect[2][0] = x3;
vect[2][1] = y3;
vect[3][0] = x4;
vect[3][1] = y4;
}
template <typename R> Rectangle<R>::~Rectangle()
{
cout << "The rectangle object has been deleted." << endl;
}
template <typename R> float Rectangle<R>::length(R a1,R b1,R a2,R b2)
{
float len;
len = (a2 - a1)*(a2 - a1) + (b2 - b1)*(b2 - b1);
len = sqrt(len);
return len;
}
template <typename R> float Rectangle<R>::area()
{
float Area;
Area = length(vect[0][0], vect[0][1], vect[1][0], vect[1][1]);
Area *= length(vect[0][0], vect[0][1], vect[3][0], vect[3][1]);
return Area;
}
template <typename R> float Rectangle<R>::perimeter()
{
float Perimeter;
Perimeter = 2*length(vect[0][0], vect[0][1], vect[1][0], vect[1][1]);
Perimeter += 2*length(vect[0][0], vect[0][1], vect[3][0], vect[3][1]);
return Perimeter;
}
// Problem remains with this operator overload (when functions are moved to Rectangle.h)
template <typename R> ostream &operator<<(ostream &output, Rectangle <R> &p)
{
cout << "(" << p.vect[0][0] << "," << p.vect[0][1] << ")" << endl;
cout << "(" << p.vect[1][0] << "," << p.vect[1][1] << ")" << endl;
cout << "(" << p.vect[2][0] << "," << p.vect[2][1] << ")" << endl;
cout << "(" << p.vect[3][0] << "," << p.vect[3][1] << ")" << endl;
return output;
}
ERRORS LIST:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall Rectangle<int>::Rectangle<int>(int,int,int,int,int,int,int,int)" (??0?$Rectangle@H@@QAE@HHHHHHHH@Z) referenced in function _main C:\Users\Alex\Desktop\C++ Projects\OOP_Test_1\OOP_Test_1\Main.obj OOP_Test_1
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Rectangle<int>::~Rectangle<int>(void)" (??1?$Rectangle@H@@QAE@XZ) referenced in function _main C:\Users\Alex\Desktop\C++ Projects\OOP_Test_1\OOP_Test_1\Main.obj OOP_Test_1
Error 3 error LNK2019: unresolved external symbol "public: float __thiscall Rectangle<int>::area(void)" (?area@?$Rectangle@H@@QAEMXZ) referenced in function _main C:\Users\Alex\Desktop\C++ Projects\OOP_Test_1\OOP_Test_1\Main.obj OOP_Test_1
Error 4 error LNK2019: unresolved external symbol "public: float __thiscall Rectangle<int>::perimeter(void)" (?perimeter@?$Rectangle@H@@QAEMXZ) referenced in function _main C:\Users\Alex\Desktop\C++ Projects\OOP_Test_1\OOP_Test_1\Main.obj OOP_Test_1
Error 5 error LNK2019: 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 Rectangle<int> &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Rectangle@H@@@Z) referenced in function _main C:\Users\Alex\Desktop\C++ Projects\OOP_Test_1\OOP_Test_1\Main.obj OOP_Test_1
Error 6 error LNK1120: 5 unresolved externals C:\Users\Alex\Desktop\C++ Projects\OOP_Test_1\Debug\OOP_Test_1.exe OOP_Test_1
I found out that moving my functions from separate class.cpp file to class.h, where their prototypes are declared, helps, but not always. Output operator overload still doesn't work and the same mistake (but only 1) emerges even with functions in class.h.
ERROR LIST (after moving functions to header file):
Error 2 error LNK2019: 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 Rectangle<int> &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Rectangle@H@@@Z) referenced in function _main C:\Users\Alex\Desktop\C++ Projects\OOP_Test_1\OOP_Test_1\Main.obj OOP_Test_1
Error 3 error LNK1120: 1 unresolved externals C:\Users\Alex\Desktop\C++ Projects\OOP_Test_1\Debug\OOP_Test_1.exe 1 1 OOP_Test_1
UPD: I understood, what was wrong with templates implementation in class.cpp and their definition in class.h. But I still don't know, how to deal with operator overload. I'm reading some C++ reference now, nevertheless I'll be glad to get some hints. I'll appreciate any help. Thank you.