260 likes | 369 Views
Template. Implicit 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;
E N D
Template Implicit 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 <class TYPE1> 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 <class csymbol> .. or template <typename tsymbol> class can be used for both class and variable type, but type name only refers to variable types
Function template with two types template <class TYPE1, class TYPE2> 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 <typename TYPE1, typename TYPE2> double ssqq(TYPE1 & a, TYPE2 & b) { return((double)(a*b));} template <typename TYPE3> 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 <typename XTYPE> class position { XTYPE x, y, z; public: position(){}; position(XTYPE px, XTYPE py, XTYPE pz) { x = px; y=py; z=pz; } position(position<XTYPE> & 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 <class XTYPE> void position<XTYPE>::print() { printf("x = %lf y = %lf z = %lf\n",(double)x,(double)y,(double)z); } template <class XTYPE> XTYPE position<XTYPE>::theta() { return( (XTYPE) acos(z/this->r())); } template <class XTYPE> XTYPE position<XTYPE>::phi() { return( (XTYPE) atan2(this->y, this->x) ); }
Using template class position<float> 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<double> ra[5]; // declare a position array for (i=0; i<5; i++) { ra[i].setx(11.0 + (double)i); ra[i].sety(20.0 + (double)i); ra[i].setz(30.0 + (double)i); }
Complex class #include <complex> using namespace std; Headfile: complex<double> ca, cb(1.2, 6.1); ca = complex<double>(2.4, 5.3); 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<double> cc[4]; cc[0] = ca = complex<double>(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 XT> class polynomial { }; template <class XTYPE> 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 <class XTYPE> polynomial<XTYPE>::polynomial<XTYPE> (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 <double> a(1.0, 2.0); cout << a << “\n” Output 結果: (1, 2) complex<double> b; cin >> b; 輸入格式為: (1.0, 2.0)
練習二. 將 Matrix class 加上 template for double and complex<double> typedef complex<double> CMPLX; // short-hand for complex<double> template <class XT> class Matrix { protected: XT *xpt; int nrow, ncol; public: . . . . // constructor, member function and frieds. };
Constructors Matrix<XT>(){;} Matrix<XT>(const int, const int); Matrix<XT>(const Matrix<XT> &); Matrix<XT>(int, int ,XT*); ~Matrix<XT>() { this->nrow = this->ncol = 0; delete [] this->xpt; } XT is the symbol defined at the declaration of a class object. class Matrix<double> m1(3,4), m2; class matrix<complex<double> > c1, c2;
Example of constructor code built outside the class template <class XT>Matrix<XT>::Matrix<XT>(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<(n*m); i++) this->xpt[i] = ap[i]; } } }
Manipulation member functions 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<XT> getcol(int) const; // get a column form the matrix Matrix<XT> getrow(int) const; // get a row from the matrix
Example of Member function built outside the class template <class XT> Matrix<XT> Matrix<XT>::getcol(int nr) const { int i; Matrix<XT> colv(this->nrow, 1); for (i=0; i < this->nrow; i++) colv.xpt[i] = this->get(i, nr); return colv; }
Utility member functions double norm() const; // remain double inline double abs() const {return sqrt(this->norm());} Matrix<XT> transport() const; Matrix<XT> adjoint() const; // for complex -- transport and conjugate adjoint: 共軛轉置矩陣 程式中若須要區分 double 和 complex, 可用 sizeof(XT). 當 sizeof (XT) <= 8 adjoint = transport In code norm: 先把 xx cast 轉成 complex, 取共軛再相乘, 乘完再取 real. template <class XT> double Matrix<XT>::norm() XT xx; xx = this->xpt[i]; sum = sum + (conj((CMPLX)xx) * xx).real(); 不然就必須把 Matrix<double> 和 Matrix<CMPLX> 分開寫兩個程式.
Unary operator Declaration inside class: Matrix<XT> &operator= (const Matrix<XT>); Matrix<XT> &operator+=(const Matrix<XT>); Matrix<XT> &operator-=(const Matrix<XT>); Code outside the class: template <class XT> Matrix<XT> &Matrix<XT>::operator+=(const Matrix<XT> m2) { int i; if ((this->ncol==m2.ncol) && (this->nrow==m2.nrow)) for (i=0; i<this->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 defined friend functions template <class TT> friend ostream &operator<<(ostream &, Matrix<TT>); template <class TT> friend Matrix<TT> operator+(Matrix<TT>, Matrix<double>); template <class TT> friend Matrix<CMPLX> operator+(Matrix<TT>, Matrix<CMPLX>); template <class TT> friend Matrix<TT> operator-(Matrix<TT>, Matrix<double>); template <class TT> friend Matrix<CMPLX> operator-(Matrix<TT>, Matrix<CMPLX>); template <class TT> friend Matrix<TT> operator*(double, Matrix<TT>); template <class TT> friend Matrix<CMPLX> operator*(CMPLX, Matrix<TT>); template <class TT> friend Matrix<TT> operator*(Matrix<TT>, double); template <class TT> friend Matrix<CMPLX> operator*(Matrix<TT>, CMPLX); template <class TT> friend Matrix<TT> operator*(Matrix<TT>, Matrix<double>); template <class TT> friend Matrix<CMPLX> operator*(Matrix<TT>, Matrix<CMPLX>); 每一個用任何 class 或 變數 取代 TT 所得的函數, 都被當作是 class Matrix 的 friend function.
Template friend operator built outside the class template <class XT> Matrix<CMPLX> operator+(Matrix<XT> m1, Matrix<CMPLX> m2) { int i; Matrix<CMPLX> 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<CMPLX>(); } return m3; }
Exmaple of program using Matrix<CMPLX> class #include <cstdlib> #include <iostream> #include "ytluMatrix2.h“// CMPLX = complex<double> 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<CMPLX> a1(n, m, xx), a3, a4; Matrix<CMPLX> 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; }
Example of using Matrix<double> #include <cstdlib> #include "ytluMatrix2.h“// typedef complex<double> 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<double> a1(3, 4, xx), a3, a4; Matrix<double> 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; }