The workaround is pretty simple. Write the header file as follows (File: Rectangle.h) in which we declare some methods, constructors and operators for our class:
/* * Rectangle.h * * Created on: Nov 2, 2014 * Author: Pantelis Sopasakis */ #ifndef RECTANGLE_H_ #define RECTANGLE_H_ #include <iostream> using namespace std; template<typename T> class Rectangle { T *x, *y; public: Rectangle(); Rectangle(const Rectangle& other); Rectangle<T>(T x, T y); virtual ~Rectangle(); T area(); Rectangle operator+ (const Rectangle& r); void operator=(const Rectangle& obj); }; #include "Rectangle.cpp" #endif /* RECTANGLE_H_ */
and note that inside the header file we have included the implementation (File: Rectangle.cpp).
The cpp file reads as follows:
#include "Rectangle.h" #ifndef RECTANGLE_IMPL__ #define RECTANGLE_IMPL__ template<typename T> T Rectangle<T>::area() { return *x * *y; } template<typename T> Rectangle<T>::Rectangle() { x = new T; y = new T; *x = (T)1; *y = (T)1; } template<typename T> Rectangle<T>::Rectangle(T a, T b){ x = new T; y = new T; *x = a; *y = b; } template<typename T> Rectangle<T>::~Rectangle() { if (x!=0){ delete x; x = 0; } if (y != 0) { delete y; y = 0; } } template<typename T> Rectangle<T>::Rectangle(const Rectangle& other){ this->x = new T; this->y = new T; *this->x = *other.x; *this->y = *other.y; } template<typename T> Rectangle<T> Rectangle<T>::operator+ (const Rectangle& r){ T x_ = (*x) + *(r.x); T y_ = (*y) + *(r.y); Rectangle c(x_, y_); return (c); } template<typename T> void Rectangle<T>::operator=(const Rectangle& obj) { *x = *(obj.x); *y = *(obj.y); return; } #endif
(the guards RECTANGLE_IMPL_ are necessary!). So that' all! Let's see how it works in practice.
In our main file we include the header file only (which includes the implementation).
#include <iostream> #include <iomanip> #include "Rectangle.h" using namespace std; int main() { Rectangle<int> a(2,3); cout << setprecision(3) << "Area(a) = " << a.area() << "\n"; Rectangle<float> *r = new Rectangle<float>(4.5, 2.5); cout << setprecision(3) << "Area(r) = " << r->area() << "\n"; Rectangle<float> q(1.1,2.2); q = q + (*r); cout << setprecision(3) << "Area(q) = " << q.area() << "\n"; cout << "OK!\n"; return 0; }
And what is with a class that has a templated method?
ReplyDeleteclass A
{
template
foo( B const & b );
};
It's basically the same: you simply put the implementation of your templated member function into that cpp file.
ReplyDeleteIf you have a bunch of ordinary member functions that you prefer to put into a classic cpp file, do so. You can give the file for your template implementation another extension, say *.hpp.
This allows to have non inline member functions.
Thank you my teacher makes us do it this way
ReplyDelete