210 likes | 300 Views
Class operators. class polynomial. class polynomial { protected: int n; double *a; public: polynomial(){}; … ..; // constructor ~polynomial(); // destructor //member functions ...
E N D
class polynomial class polynomial { protected: int n; double *a; public: polynomial(){}; …..; // constructor ~polynomial(); // destructor //member functions ... double f (const double) const; // polynomial value // friend functions and operators friend polynomial operator+ (const polynomial, const polynomial); friend polynomial operator- (const polynomial, const polynomial); friend polynomial operator* (const double, const polynomial); }; // end of class definition
constructors 1. polynomial::polynomial(){}; // an empty polynomial 2. polynomial::polynomial(const int nn){ n = nn; a = new double[n+1];} // allocate space for coefficients, but don’t assign values. 3. polynomial::polynomial(const int nn, const double *c) { int j; n = nn; a = new double [n+1]; for (j=0; j<=n; j++) a[j] = c[j]; } // assign value for each coefficients. 4. polynomial::polynomial(const polynomial & p1) { int j; n = p1.n; a = new double [n+1]; for (j=0; j<=n; j++) a[j] = p1.a[j]; } // copy data from another polynomial
Constructor • Allow multiple constructors, same principle as function overload. • Function name of constructor: polynomial:: polynomial( arguments) {…; …; …; } • No function type, no return variables.
Dynamic allocation in c++ In C: #include <stdlib.h> pointer variable = malloc(total_memory_size); or pointer varibale = calloc(dim, size_of_each_varible); 釋放記憶: void free(void *ptr); In C++: double pointer = new double [dimension]; 釋放記憶: delete [] pointer;
Copy constructor polynomial::polynomial(const polynomial & p1) { int j; this->n = p1.n; this->a = new double [n+1]; for (j=0; j<=n; j++) this->a[j] = p1.a[j]; } // copy data from another polynomial
Pass by reference Pass by value: double ssqq(double a) { a = 2.0 * a; return(a*a); } Call: double aa = ssqq(a); // a 不變 Pass by address: double ssqq(double *a) { *a = 2.0 * (*a); return((*a)*(*a)); } Call: double aa = ssqq(&ra); // ra 2(ra) Pass by reference: double ssqq(double &a) { a = 2.0 * a; return(a*a); } Call: double aa = ssqq(a); // a 2a
Deconstructor class polynomial { protected: int n; double *a; public: …; …; ~polynomial{ delete [] this->a; } }; polynomial p1(5, acoef); // 宣告 5 階多項式 p1.~polynomial(); // 釋放 p1.a[6] 的記憶空間
Assignment operator= Assignment operator is a member function: p1 = p2; // syntax equivalent to p1.operator=(p2) polynomial& polynomial::operator=(const polynomial & p1) { int i; if (this->n > 0) delete [] this->a; this->n = p1.n; this->a = new double[this->n + 1]; for (i=0; i<=n; i++) this->a[i] = p1.a[i]; return(*this); }
operators polynomial operator* (const double rr, const polynomial p1) { int i; polynomial p2(p1); for (i=0; i<=p1.n; i++) p2.a[i] *= rr; return(p2); } Operators: +, -, *, /, % >, <, >=, <=, >>, << [], ++, --, +=, -= *=, %=
operators • Operator is a friend function. • polynomial p1(5, acoef), p2(4, bceof); polynomial p3 = p1 + p2; 可以寫成 p3 = operator+ (p1, p2) • Function overlaod 的原則可以運用到 operator 的定義. example double * polynomial; polynomial * double; polynomial * polynomial;
Polynomial operator + polynomial operator+(polynomial p1, polynomial p2) { int i; if (p1.n > p2.n) { polynomial pp(p1); for (i=0; i<=p2.n; i++) pp.a[i] += p2.a[i]; return(pp); } else { polynomial pp(p2); for (i=0; i<=p1.n; i++) pp.a[i] += p1.a[i]; return(pp); } }
polynomial operator - if (p1.n > p2.n) { polynomial pp(p1); for (i=0; i<=p2.n; i++) pp.a[i] -= p2.a[i]; return(pp); } else { polynomial pp(p2); pp = (-1.0) * pp; for (i=0; i<=p1.n; i++) pp.a[i] += p1.a[i]; return(pp); }
Polynomial operator* polynomial operator* (const polynomial p1, const polynomial p2) { int i, j, n3=p1.n+p2.n; double sum; polynomial p3(n3); for (i=0; i<=n3; i++) { sum = 0.0; for (j=0; j<=i; j++) if ((j<=p1.n) && (i-j)<= p2.n) sum += (p1.a[j]*p2.a[i-j]); p3.a[i] = sum; } return(p3); }
Polynomial operator/ n3 = p1.n – p2.n; if (n3 < 0) { n3 = 0; polynomial p3(n3); p3.a[0] = 0.0; return(p3); } else { polynomial p3(n3); polynomial pp(p1); for (i=n3; i>=0; i--) { ncur = pp.n - n3 + i; att = pp.a[ncur] / p2.a[p2.n]; p3.a[i] = att; for (j=0; j<=p2.n; j++) pp.a[pp.n-n3+i-p2.n+j] -= att*p2.a[j]; } return(p3); }
Polynomial operator % poynomial p1 % polynomial p2 留下餘數 p3, 階數小於 p2. 程式與上頁相同, 但回傳是留下來的餘 多項式. n3 = p2.n – 1; 但要留意 p3.a 的高次項係數為零時, 要將階數下降 n3 = p2.n – 1; while ((fabs(pp.a[n3]) < 1.0e-7) && (n3>0) ) { n3 --; }
practice Write a polynomial class with constructors, member functions and operators for the c++ programs. The class require the following minimal features: • Copy constructor. • Operators: +, -, *, /, %.
Class Matrix Example class Matrix { protected: int nrow, ncol; double *xpt; public: constructors; member_functions; friend_operators; }; nrow: number of rows ncol: number of columns xpt : pointer for memory reallocation for matrix elements
Plan for construction of Matrix class Row vector Square matrix Column vector Derived class Template with double and complex General matirx (n x m) Base class
注意要點 • 每一個 class 編輯器都會自動設兩個 member functions: 一個 • desrtuctor, ~class(). 另一個是 class::operator=(class). Destructor • 釋放 member 中的 array. 而等號運算是 copy 另一個 class 再 • 把 members 的值轉過去. • 但是目前 Matrix 的結構中, xpt[n*m] 的 array 並非是 class member. • 因此編輯器預設的 destrcutor 不會消滅 array xpt[]. 而等號算符會 • 將兩個 Matrix 的 xpt 指標, 指向同一記憶位址, 產生錯誤運算. • 3. 因此, 等號算符和 destructor 都必須再重新 overload.
Matrix & Matrix::operator=(Matrix b) { if (this->dim() > 0) delete [] this->xpt; //去除舊陣列 this->ncol = b.ncol; this->nrow = b.nrow; if (this->dim() > 0 ) { this->xpt = new double [this->dim()]; //建新陣列 if (this->xpt != NULL) for (i=0; i<this->dim(); i++) this->xpt[i] = b.xpt[i]; //copy b 矩陣值 else this->ncol = this->nrow = 0; } return *this; } Destructor ~Matrix() { delete [] this->xpt; this->ncol = this->nrow = 0; }