Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 13 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
13
Dung lượng
148,29 KB
Nội dung
292 Chương 9 KHUÔNHÌNH(TEMPLATE) § 1. KHUÔNHÌNH HÀM 1.1. Khái niệm khuônhình hàm Xét hàm max(x,y) ñể tính max của hai ñối. Rõ ràng x và y có thể có bất kỳ kiểu nào (kiểu chuẩn của C ++ , kiểu cấu trúc, kiểu hợp hoặc kiểu ñối tượng) miễn sao chúng có một thứ tự nào ñấy. Nếu không dùng khuôn hình, thì cần xây dựng nhiều hàm (ñược ñịnh nghĩa chồng) ứng với các kiểu khác nhau của x và y. Với khuôn hình, ta có thể ñịnh nghĩa một mẫu cho một họ các hàm tương ứng, bằng cách xem kiểu dữ liệu như một tham số (ñối). 1.2. Khai báo khuônhình hàm Các ñối ứng với các kiểu dữ liệu ñược khai báo như sau: template <class T1, class T2, , class Tm> Chú ý: + Khuônhình hàm trong ñó có sử dụng các ñối T1, T2, .,Tm phải ñược viết ngay sau dòng khai báo nói trên. + Các ñối T1, T2, .,Tm là ñối của chỉ khuônhình hàm này. 1.3. Cách xây dựng khuônhình hàm Các khuônhình hàm ñược xây dựng sau khai báo các ñối như trong 1.2. Nội dung một khuônhình hàm cũng giống như một hàm thông thường, ngoại trừ một ñiều: các kiểu dữ liệu cụ thể ñược thay bằng các ñối khai báo ở trên. Ví dụ khuônhình hàm max ñược xây dựng như sau: template <class T> T max(T x, T y) { return (x>y) ? x : y ; } 1.4. Cách sử dụng khuôn hình hàm Khuônhình hàm ñươc sử dụng thông qua lời gọi hàm. Khi sử dụng khuônhình này trong chương trình thì Trình biên dịch sẽ sản sinh một hàm tương ứng với kiểu dữ liệu trong lời gọi 293 Ví dụ: Sử dụng khuônhình hàm max class A { … }; int a, b, c; A u, v, w; c = max(a,b); w = max(u,v); Chú ý: Có thể dùng khuônhình hàm max ñối với các kiểu dữ liệu chuẩn của C ++ cũng như kiểu ñối tượng bất kỳ, miễn sao có thể áp dụng phép so sánh > 1.5. ðịnh nghĩa chồng khuônhình hàm Có thể dùng cùng một tên ñể ñịnh nghĩa các khuônhình hàm với một trong các khác biệt sau: + Khác nhau về ñối: kiểu ñối, số ñối + Khác nhau về số kiểu dữ liệu Ví dụ: template <class T> T operator*(T , T) // Nhân 2 ñối tượng cùng kiểu template <class T> T operator*(T* , int) // Nhân dẫy ñối tượng cùng kiểu template <class T1, class T2> T operator*(T1 , T2) // Nhân 2 ñối tượng khác kiểu // ví dụ ma trận và véc tơ § 2. CÁC VÍ DỤ VỀ KHUÔNHÌNH HÀM Ví dụ 1: /* Gom khuônhình hàm: template <class T> void sap_xep(T *x, int n) template <class T> void nhap_day_dt(T *dt, int &n) template <class T> void xuat_day_dt(T *dt, int &n) ðối T biểu thi ba kiểu: + int + double + TS (lop) */ 294 #include <iostream.h> #include <conio.h> #include <math.h> class TS { private: char ht[25]; double td; public: friend istream& operator>>(istream &in, TS &t) { cout << "\nHo ten: "; in.get(t.ht,25); cout << "Tong diem: "; in >> t.td; in.ignore(); return in; } friend ostream& operator<<(ostream &out,const TS &t) { out << "\nHo ten: " << t.ht << " Tong diem: " << t.td; return out; } friend int operator>(const TS &ts1,const TS &ts2) { return (ts1.td>ts2.td) ; } } ; template <class T> void sap_xep(T *x, int n) { int i,j; T tg; for(i=1; i<n; ++i) for(j=i+1; j<=n; ++j) if( !(x[i]>x[j]) ) { tg=x[i]; x[i]=x[j]; x[j]=tg; } } 295 template <class T> void nhap_day_dt(T *dt, int &n) { cout << "\nSo doi tuong: "; cin >> n; cin.ignore(); for(int i=1; i<=n; ++i) { cout << "\nNhap doi tuong thu " << i << " : " ; cin >> dt[i]; } } template <class T> void xuat_day_dt(T *dt, int n) { for(int i=1; i<=n; ++i) cout << "\nDoi tuong thu " << i << " : " << dt[i]; } void main() { int a[10]; double b[10]; TS t[10]; int n; nhap_day_dt(a,n); sap_xep(a,n); xuat_day_dt(a,n); nhap_day_dt(b,n); sap_xep(b,n); xuat_day_dt(b,n); nhap_day_dt(t,n); sap_xep(t,n); xuat_day_dt(t,n); getch(); } Ví dụ 2: /* Chu y cach khai bao 2 doi khuôn hình: template <class T1, class T2> T2 nhan(T1 a, T2 x) { . } 296 */ #include <iostream.h> #include <conio.h> #include <math.h> #include <iomanip.h> class VT; class MT; class MT { private: int a[20][20]; int n; public: friend istream& operator>>(istream &in, MT &x); friend ostream& operator<<(ostream &out,const MT &x); VT operator*(const VT &x); } ; istream& operator>>(istream &in, MT &x) { int i,j; cout << "\n Cap ma tran N= "; in >> x.n; for(i=1; i<=x.n; ++i) for(j=1; j<=x.n; ++j) { cout << "a[" <<i<<"]["<<j<<"]= "; in >> x.a[i][j]; } return in; } ostream& operator<<(ostream &out,const MT &x) { int i,j; for(i=1; i<=x.n; ++i) { out << "\n"; for(j=1; j<=x.n; ++j) out << setw(5) << x.a[i][j]; } return out; } 297 class VT { private: int a[20]; int n; public: friend istream& operator>>(istream &in, VT &x); friend ostream& operator<<(ostream &out,const VT &x); friend class MT; } ; VT MT::operator*(const VT &x) { VT y; int i,j; y.n=n; for(i=1; i<=n; ++i) { y.a[i]=0; for(j=1; j<=n; ++j) y.a[i] += a[i][j]*x.a[j]; } return y; } istream& operator>>(istream &in, VT &x) { int i; cout << "\n Cap vec to N= "; in >> x.n; for(i=1; i<=x.n; ++i) { cout << "a[" <<i<<"]= " ; in >> x.a[i]; } return in; } ostream& operator<<(ostream &out,const VT &x) { int i; out << "\n"; for(i=1; i<=x.n; ++i) 298 out << setw(5) << x.a[i]; return out; } template <class T1, class T2> T2 nhan(T1 a, T2 x) { return a*x; } void main() { int k; double x,y; clrscr(); k = nhan(4,5); x = nhan(3,5.5); y = nhan(5.0,6.5); cout << "\nk= " << k << " x= "<< x <<" y= " << y; MT a; VT u,v; cout << "\nNhap MT a:" ; cin>>a; cout << "\nNhap VT u:" ; cin>>u; v = a*u; cout << "\nMa tran A: " << a ; cout << "\n Vec to u: " << u; cout << "\n Vec to v=Au: " << v; getch(); } § 3. KHUÔNHÌNH LỚP 3.1. Khái niệm khuônhình lớp Có thể dùng từ khoá template ñể xây dựng một khuônhình lớp trong ñó kiểu thuộc tính ñược xem như các ñối. Bằng cách ñó ta có thể tạo ra một họ các lớp giống nhau về bản chất xử lý, nhưng khác nhau về kiểu dữ liệu. 3.2. Khai báo khuônhình lớp Các ñối ứng với các kiểu dữ liệu ñược khai báo như sau: template <class T1, class T2, , class Tm> Chú ý: + Khuônhình lớp trong ñó có sử dụng các ñối T1, T2, .,Tm phải ñược viết ngay sau dòng khai báo nói trên. + Các ñối T1, T2, .,Tm là ñối của chỉ khuônhình lớp này. 3.3. Cách xây dựng khuônhình lớp 299 Các khuônhình lớp ñược xây dựng sau khai báo các ñối như trong 3.2. Nội dung một khuônhình lớp cũng giống như một lớp thông thường, ngoại trừ một ñiều: các kiểu dữ liệu cụ thể ñược thay bằng các ñối khai báo ở trên. Ví dụ khuônhình lớp ñược xây dựng như sau: template <class T> class List { T *v ; int n; public: List(int); T& operator[](int i) { return v[i] ; } } ; // Bên ngoài ñịnh nghĩa lớp template <class T> List<T>::List(int n) { v = new T[n]; size = n; } 3.4. Cách sử dụng khuônhình lớp Có thể dùng khuônhình lớp ñể tạo một các ñối tượng với các kiểu dữ liệu bất kỳ, bằng câu lệnh khai báo, new, hàm tạo. Sau ñó sử dụng các phương thức ñể xử lý các ñối tượng tạo ra. Ví dụ có thể tạo ra các ñối tượng List với kiểu dữ liệu bất kỳ như sau: List <int> x(20) ; List <A> u(30); Sau ñó dùng phương thức chỉ số và phép gán: x[3] = 7 ; u[10] = m ; // m là một ñối tượng kiểu A § 4. VÍ DỤ VỀ KHUÔNHÌNH LỚP 300 /* Mot doi T dung cho lop List Doi T bieu thi 3 kieu: + int + double + TS (lop) */ #include <iostream.h> #include <conio.h> #include <math.h> class TS { private: char ht[25]; double td; public: friend istream& operator>>(istream &in, TS &t) { cout << "\nHo ten: "; in.get(t.ht,25); cout << "Tong diem: "; in >> t.td; in.ignore(); return in; } friend ostream& operator<<(ostream &out,const TS &t) { out << "\nHo ten: " << t.ht << " Tong diem: " << t.td; return out; } friend int operator>(const TS &ts1,const TS &ts2) { return (ts1.td>ts2.td) ; } } ; template <class T> class List { private: T *t; int n; 301 public: List() { n=0; t=NULL; } List(int ); void sap_xep(); void nhap_day_dt(); void xuat_day_dt(); }; template <class T> List<T>::List(int n1) { n=n1; t = new T[n+1]; } template <class T> void List <T>::sap_xep() { int i,j; T tg; for(i=1; i<n; ++i) for(j=i+1; j<=n; ++j) if( !(t[i]>t[j]) ) { tg=t[i]; t[i]=t[j]; t[j]=tg; } } template <class T> void List<T>::nhap_day_dt() { if (t!=NULL) delete t; cout << "\nSo doi tuong: "; cin >> n; cin.ignore(); t = new T[n+1]; for(int i=1; i<=n; ++i) { cout << "\nNhap doi tuong thu " << i << " : " ; cin >> t[i]; } } template <class T> void List<T>::xuat_day_dt() { for(int i=1; i<=n; ++i) [...]... ts.sap_xep(); ts.xuat_day_dt(); getch(); } BÀI T P CHƯƠNG 9 Bài 1 Xây d ng khuôn hình hàm ñ s p x p m t dãy các ph n t cùng ki u Sau ñó hãy áp d ng khuôn hình hàm này ñ s p x p m t dãy s th c, và m t dãy các chu i ký t (ki u d li u char*) Bài 2 Hãy ch ra nh ng yêu c u nào ñ i v i các ki u d li u có th truy n ñư c vào cho tham s ki u c a khuôn hình hàm sum dư i ñây: template T sum(T a[], int n) { T... x=y=0; } SP(float x1, float y1) { x=x1; y=y1; } // các phương th c khác }; Bài 4 Xây d ng khuônhình l p DS (Dãy s ), sau ñó áp d ng cho m t l p dãy s th c và cho m t l p dãy s ph c template class DS { T a[n]; public: T& operator[] (int i) { return a[i]; } // các phương th c khác }; Bài 5 Xây d ng khuônhình l p ngăn x p (Stack), sau ñó áp d ng cho m t l p ngăn x p các s th c và m t l p... th c và m t l p ngăn x p các s ph c template class Stack { int top; T element[n]; public: Stack() { top=0; } void push(T e); void pop(T& e); // các phương th c khác }; 303 Bài 6 Xây d ng khuôn hình l p hàng ñ i (Queue), sau ñó áp d ng cho m t l p hàng ñ i các s th c và m t l p hàng ñ i các s ph c template class Queue { int head; T element[n]; public: Queue() {head=0; } void enqueue(T . chỉ khuôn hình hàm này. 1.3. Cách xây dựng khuôn hình hàm Các khuôn hình hàm ñược xây dựng sau khai báo các ñối như trong 1.2. Nội dung một khuôn hình. chỉ khuôn hình lớp này. 3.3. Cách xây dựng khuôn hình lớp 299 Các khuôn hình lớp ñược xây dựng sau khai báo các ñối như trong 3.2. Nội dung một khuôn hình