Template Implicit function overload
Function overload Function overload double ssqq(double & a, double & b) { return(a*b);} float ssqq(float & a, float & b) {return(a*b);} int ssqq(int & a, int & b) {return(a*b);} main() { int na=3, nb=-5; float ra=2.1, rb=-3.4; double da=4.7, db=-5.6; cout << "integer : " << ssqq(na, nb) << "\n"; cout << "float : " << ssqq(ra, rb) << "\n"; cout << "double : " << ssqq(da, db) << "\n"; system("pause"); return(0); }
template template TYPE1 ssqq(TYPE1 & a, TYPE1 & b) { return (TYPE1)(a*b);} main() { int na=3, nb=-5; float ra=2.1, rb=-3.4; double da=4.7, db=-5.6; cout << "integer : " << ssqq(na, nb) << "\n"; cout << "float : " << ssqq(ra, rb) << "\n"; cout << "double : " << ssqq(da, db) << "\n"; system("pause"); return(0); } template.. or template class can be used for both class and variable type, but type name only refers to variable types
Function template with two types Function template with two types template double ssqq(TYPE1 & a, TYPE2 & b) { return (double)(a*b);} main() { int na=3, nb=-5; float ra=2.1, rb=-3.4; double da=4.7, db=-5.6; cout << "2 integer : " << ssqq(na, nb) << "\n"; cout << "float * double : " << ssqq(ra, db) << "\n"; cout << "double * float : " << ssqq(da, rb) << "\n"; system("pause"); return(0); }
Template-function overload Template-function overload template double ssqq(TYPE1 & a, TYPE2 & b) { return((double)(a*b));} template TYPE3 ssqq(TYPE3 & a) { return((TYPE3)(a*a)); } main() { int na=3, nb=-5; float ra=2.1, rb=-3.4; double da=4.7, db=-5.6; cout << "2 integer : " << ssqq(na, nb) << "\n"; cout << "float & integer : " << ssqq(ra, nb) << "\n"; cout << "float & double : " << ssqq(rb, db) << "\n"; cout << "1 integer : " << ssqq(na) << "\n"; cout << "1 float : " << ssqq(ra) << "\n"; cout << "1 double: " << ssqq(da) << "\n";
Template class Template class template class position { XTYPE x, y, z; public: position(){}; position(XTYPE px, XTYPE py, XTYPE pz) { x = px; y=py; z=pz; } position(position & r) {x=r.x; y=r.y; z=r.z;} //member functions XTYPE r() {return (XTYPE)(sqrt((double)(x*x+y*y+z*z)));} void setx(XTYPE rx){ x=rx;} void sety(XTYPE ry){ y=ry;} void setz(XTYPE rz){ z=rz;} XTYPE getx() { return(x);} XTYPE gety() { return(y);} XTYPE getz() { return(z);} XTYPE phi(); XTYPE theta(); void print(); };
Member function of template class template void position ::print() { printf("x = %lf y = %lf z = %lf\n",(double)x,(double)y,(double)z); } template XTYPE position ::theta() { return( (XTYPE) acos(z/this->r())); } template XTYPE position ::phi() { return( (XTYPE) atan2(this->y, this->x) ); }
Using template class position r(3.0F, 4.0F, 5.0F); r.print(); r.setx(3.0); r.print(); printf("r=%f phi=%f theta=%f\n",r.r(), 180.0F*r.phi()/MyPi, 180.0F*r.theta()/MyPi); position ra[5]; // declare a position array for (i=0; i<5; i++) { ra[i].setx( (double)i); ra[i].sety( (double)i); ra[i].setz( (double)i); }
Complex class Complex class #include using namespace std; complex ca, cb(1.2, 6.1); ca = complex (2.4, 5.3); Headfile: Declare:
Complex functions cout << "ca = " << ca << "\n"; cout <<" real = " << ca.real() << "\n"; cout <<" imag = " << ca.imag() << "\n"; cout << "cb = " << cb << "\n"; cout << "ca+cb = " << (ca+cb) << "\n"; cout << "ca*cb = " << ca*cb << "\n"; cout << ca << "conjugate = "<< conj(ca) << "\n"; cout << "exp(ca) = " << exp(ca) << "\n"; cout << "abs(ca) = " << abs(ca) << "\n";
complex array complex cc[4]; cc[0] = ca = complex (0.0, 1.0); for (i=1; i<4; i++) cc[i] = cc[i-1] * ca; for (i=0; i<4; i++) cout << i << " : " << cc[i] << "\n";
Practice Using Newton ’ s method to solve a root for a polynomial. Write the polynomial in a form of template class to allow complex coefficients. dx = f(x) / df(x); x = x – dx; All these variables will be double or complex numbers.
template class polynomial { }; template class polynomial { }; template class polynomial { int n; XTYPE *a; public: polynomial(int); //constructor polynomial(int, XTYPE *); //member functions XTYPE f (const XTYPE) const; XTYPE df(const XTYPE) const; void print() const; void coef(XTYPE *); inline void coef(int n, XTYPE x) {a[n] = x;} }; // end of class definition
constructor template polynomial ::polynomial (int nn, XTYPE *c) { int i; n = nn; a = new XTYPE[n+1]; if (a==NULL) n=0; else { for (i=0; i <= n; i++) a[i] = c[i]; }
I/O format for complex number complex a(1.0, 2.0); cout << a << “ \n ” Output 結果 : (1, 2) complex b; cin >> b; 輸入格式為 : (1.0, 2.0)
練習二. 將 Matrix class 加上 template for double and complex 練習二. 將 Matrix class 加上 template for double and complex typedef complex CMPLX; // short-hand for complex template class Matrix { protected: XT *xpt; int nrow, ncol; public:.... // constructor, member function and frieds. };
Matrix (){;} Matrix (const int, const int); Matrix (const Matrix &); Matrix (int, int,XT*); ~Matrix () { this->nrow = this->ncol = 0; delete [] this->xpt; } Constructors XT is the symbol defined at the declaration of a class object. class Matrix m1(3,4), m2; class matrix > c1, c2;
template Matrix ::Matrix (int n, int m, XT *ap) { int i; if ((n > 0) && (m > 0) ) { this->xpt = new XT [n*m]; if (this->xpt != NULL) { this->nrow = n; this->ncol = m; for (i=0; i xpt[i] = ap[i]; } Example of constructor code built outside the class
inline int row() const { return this->nrow;} inline int col() const { return this->ncol;} inline int dim() const { return (this->nrow * this->ncol) ;} inline int CV(const int i,const int j) const { return(ncol*i + j);} inline XT get(const int i, const int j) const { return this->xpt[CV(i,j)]; } inline void set(const int i, const int j, XT xx) { this->xpt[CV(i,j)] = xx; } inline XT get(const int i) const { return this->xpt[i]; } inline void set(const int i, XT xx) { this->xpt[i] = xx; } Matrix getcol(int) const; // get a column form the matrix Matrix getrow(int) const; // get a row from the matrix Manipulation member functions
template Matrix Matrix ::getcol(int nr) const { int i; Matrix colv(this->nrow, 1); for (i=0; i nrow; i++) colv.xpt[i] = this->get(i, nr); return colv; } Example of Member function built outside the class
double norm() const; // remain double inline double abs() const {return sqrt(this->norm());} Matrix transport() const; Matrix adjoint() const; // for complex -- transport and conjugate Utility member functions adjoint: 共軛轉置矩陣 程式中若須要區分 double 和 complex, 可用 sizeof(XT). 當 sizeof (XT) <= 8 adjoint = transport In code norm: 先把 xx cast 轉成 complex, 取共軛再相乘, 乘完再取 real. template double Matrix ::norm() XT xx; xx = this->xpt[i]; sum = sum + (conj((CMPLX)xx) * xx).real(); 不然就必須把 Matrix 和 Matrix 分開寫兩個程式.
Declaration inside class: Matrix &operator= (const Matrix ); Matrix &operator+=(const Matrix ); Matrix &operator-=(const Matrix ); Unary operator Code outside the class: template Matrix &Matrix ::operator+=(const Matrix m2) { int i; if ((this->ncol==m2.ncol) && (this->nrow==m2.nrow)) for (i=0; i dim(); i++) this->xpt[i] += m2.xpt[i]; else { this->ncol = this->nrow = 0; delete [] this->xpt; } return *this; } // the code is same for both double and complex.
template friend ostream &operator ); template friend Matrix operator+(Matrix, Matrix ); template friend Matrix operator-(Matrix, Matrix ); template friend Matrix operator*(double, Matrix ); template friend Matrix operator*(CMPLX, Matrix ); template friend Matrix operator*(Matrix, double); template friend Matrix operator*(Matrix, CMPLX); template friend Matrix operator*(Matrix, Matrix ); Template defined friend functions 每一個用任何 class 或 變數 取代 TT 所得的函數, 都被當作是 class Matrix 的 friend function.
template Matrix operator+(Matrix m1, Matrix m2) { int i; Matrix m3; if ((m1.nrow == m2.nrow) && (m1.ncol == m2.ncol)) { m3 = m1; for (i=0; i<m3.dim(); i++) m3.xpt[i] += m2.xpt[i]; } else { m3.~Matrix (); } return m3; } Template friend operator built outside the class
#include #include "ytluMatrix2.h “ // CMPLX = complex using namespace std; int main() { int n=3, m=4, i; CMPLX xx[12]; for (i=0; i<12; i++) xx[i] = CMPLX((double)i, (double)i*0.5 ); Matrix a1(n, m, xx), a3, a4; Matrix a2(m, n, xx); cout << " a1 = " << a1 ; cout << " 2nd COlumn of a1 " << a1.getcol(1); cout << " 2nd row of a1 " << a1.getrow(1); cout << " a2 = " << a2; a3 = a4 = a1; cout << "a1 = " << a1 << "a3 = " << a3 << "a4 = " << a4; cout << "a1 + a3 + a4 = " << (a1+a3+a4); cout << "a1 * (1i) " << a1 * CMPLX(0.0, 1.0); cout << "a1 * 2.0 " << a1 * 2.0; cout << "(1i) * a1 *2 " << CMPLX(0.0,1.0)*a1*2.0; cout << "a1 * a2" << a1 * a2; system("pause"); return 0; } Exmaple of program using Matrix class
#include #include "ytluMatrix2.h “ // typedef complex CMPLX using namespace std; int main() { int n=3, m=4; double xx[12] = { 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.}; Matrix a1(3, 4, xx), a3, a4; Matrix a2(4, 3, xx); cout << " a1 = " << a1 ; cout << " 2nd Column of a1 " << a1.getcol(1); cout << " 2nd row of a1 " << a1.getrow(1); cout << " a2 = " << a2; a3 = a4 = a1; cout << "a1 = " << a1 << "a3 = " << a3 << "a4 = " << a4; cout << "a1 + a3 + a4 = " << (a1+a3+a4); cout << "a3 - a4 " << (a3-a4); cout << "a1 - a3 -a4 " << (a1-a3-a4); cout << "a1 * (1i) " << a1 * CMPLX(0.0, 1.0); cout << "a1 * 2.0 " << a1 * 2.0; cout << "(1i) * a1 *2 " << CMPLX(0.0,1.0)*a1*2.0; cout << "a1 * a2" << a1 * a2; cout << "(1i)*a1 *a2" << CMPLX(0.0, 1.0)*a1*a2; system("pause"); return 0; } Example of using Matrix