Chapter6 Lập trình tổng quát c++

25 571 6
Chapter6 Lập trình tổng quát c++

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Lập trình tổng quát c++

Lập trình Chương 6: Lập trình tổng quát 8/6/2012 Nội dung 6.1 Khuân mẫu hàm (Function template) 6.2 Khuân mẫu lớp 6.3 Thuật tốn tổng qt Chương 5: Lập trình tổng quát © 2010 - KimThoa 6.1 Khuân mẫu hàm Ví dụ hàm tìm giá trị lớn a Tìm max hai số nguyên int max(const int &a, const int &b){ return (a > b)? a: b; } b Tìm max hai số thực float max(const float &a, const float &b){ return (a > b)? a: b; } Nhận xét: Các hàm tìm max hai số khác kiểu liệu, ậ ệ , thuật toán giống Tương tự có nhiều hàm khác kiểu liệu, không khác thuật tốn Giải pháp: tổng qt hóa hàm khác kiểu ⇒ khuôn mẫu hàm Chương 5: Lập trình tổng qt © 2010 - KimThoa Ví dụ tổng qt hóa hàm max Tham số khn mẫu template T max(const T &a,const T &b){ return (a > b)? a: b; } Sử dụng từ khóa class typename để khai báo tham số khuôn mẫu Khuôn mẫu hàm inline template inline T max(const T &a,const T &b) { return (a > b)? a : b; } Sử dụng int max(5,7); Chương 5: Lập trình tổng quát Compiler t hàm th kh ô mẫu C il ẽ tạo ột hà theo khuôn ẫ có dạng int max(const int&, const int&) © 2010 - KimThoa Ví dụ sử dụng void main() { int i1 = 1, i2 = 5; double d1 = 1.0, d2 = 2.0; double d = max(d1,d2); // max(double,double) char c = max('c','a'); // max(char, char) d = max(i1,d1); // error: ambiguous c = max('c',i1); // error: ambiguous d = max(d1,i1); // OK: explicit qualification c = max('c',i1); // OK: explicit qualification } Áp dụng cho complex? class complex{ double real, imag; public: complex(double r=0,int r 0,int i=0); double get_real(); void set_real(double); doub e get_ ag(); double get imag(); void set_imag(double); }; Chương 5: Lập trình tổng quát void main{ complex c1(1.1,2.0); complex c2(2.0,2,2); complex c = max(c1,c2); }; Lỗi, lớp complex chưa ₫ịnh nghĩa phép so sánh > sử dụng hàm khn mẫu max © 2010 - KimThoa Giải pháp cho trường hợp ₫ịnh nghĩa toán tử so sánh lớn cho lớp complex p p Một khn mẫu hàm ₫ược nạp chồng hàm tên khuôn mẫu hàm tên (khác ố lượng th (khá số l tham số h ặ k ể ố kiểu ủ hất ột tham số) — Hàm tên ₫ể thực cho thuật tốn ₫ặc biệt (Ví g ự ệ ậ ặ ệ dụ, hàm max hai chuỗi ký tự có thuật tốn thực khác với tìm max hai số int double) — Khuôn mẫu hàm tên g template T max(T a, T b, T c) template T max(T* a, int n) { } { } không ₫ược này: template X max(X a, X b, X c) Chương 5: Lập trình tổng qt { } © 2010 - KimThoa Tham số khn mẫu hàm có tham số kiểu, ví dụ: template id (A& b){…} Ví dụ: template A,class void swap( A &a, B &b){ A temp = a; a = b; //₫úng b tương thích với a b = temp; //₫úng temp tương thích với b } void main(){ int a = 5; double b = 10 2; 10.2; swap(a,b); //swap(int,double) swap(b,a); //swap(double,int) } Chương 5: Lập trình tổng quát © 2010 - KimThoa Tóm lược Khi sử dụng compiler cần biết mã nguồn thực khuôn mẫu hàm, khai báo ₫ịnh nghĩa khuôn ẫ hàm ê kh ô mẫu hà nên ₫ể h d fil ⇒ sử dụng header file ửd template công khai hết phần thực Mã hàm khuôn mẫu ₫ược thực sinh khuôn mẫu hàm ₫ược sử dụng với kiểu cụ thể Một khuôn mẫu hàm ₫ược sử dụng nhiều lần với kiểu khác nhiều hàm khn mẫu ₫ược tạo ể ề ẫ Một khuôn mẫu hàm ₫ược sử dụng nhiều lần với kiểu, có hàm khn mẫu ₫ược tạo Chương 5: Lập trình tổng quát © 2010 - KimThoa Ưu/nhược ₫iểm khuôn mẫu hàm Ưu ₫iểm — Tiết kiệm ₫ược mã nguồn — Tính mở: nâng cao tính sử dụng lại, thuật tốn viết lần ế ầ sử dụng vơ số lần — Cho phép xây dựng thư viên chuẩn mạnh thư viện thuật tốn thơng dụng: chép, tìm kiếm, xếp, ế ắ ế lựa chọn,… Nhược ₫iểm ợ — Không che giấu ₫ược mã nguồn thực thi, compiler phải biết mã nguồn biên dịch — Theo dõi, tìm kiếm lỗi phức tạp, ₫ôi lỗi nằm phần sử dõi tạp dụng compiler lại báo phần ₫ịnh nghĩa khuôn mẫu hàm Chương 5: Lập trình tổng qt © 2010 - KimThoa 6.2 Khuôn mẫu lớp Nghiên cứu lớp số phức #include class IntComplex{ int real,imag; public: Complex(int r = 0, int i =0): real(r),imag(i) {} int get_real() const { return real; } int get_imag() const { return imag; } Complex operator+(const Complex& b) const { Complex z(real + b.real, imag + b.image); return z; } Complex operator-(const Complex& b) const { return Complex(real - b.real, imag - b.imag); } }; Chương 5: Lập trình tổng quát © 2010 - KimThoa 10 class DoubleComplex{ p { double real,imag; public: Complex(double r = 0, double i =0): real(r),imag(i) {} double get_real() const { return real; } g () ; double get_imag() const { return imag; } Complex operator+(const Complex& b) const { Complex z(real + b.real, imag + b.image); return z; ; } Complex operator-(const Complex& b) const { return Complex(real - b.real, imag - b.imag); } }; Hai lớ ố khác h H i lớp số phức t ê gì? Giống gì? ì? Giố h ì? Chương 5: Lập trình tổng quát © 2010 - KimThoa 11 Tương tự nhu vậy, thực tế có nhiều cấu trúc liệu khác kiểu liệu cịn hồn tồn giống phép tốn, ví dụ vector, list, complex,… Để tiết kiệm mã nguồn thực thi ⇒ tổng q g g quát hóa kiểu liệu cho lớp template class Complex{ T real,imag; public: Complex(T r = 0, T i =0): real(r),imag(i) {} T get_real() const { return real; } T get_imag() const { return imag; } Complex operator+(const Complex& b) const { Complex z(real + b.real, imag + b.image); return z; } Complex operator-(const Complex& b) const; }; Chương 5: Lập trình tổng qt © 2010 - KimThoa 12 Định nghĩa hàm thành viên bên khai báo lớp template Complex::Complex operator-(const Complex& b) const { return Complex(real - b.real, imag - b.imag); } Sử d dụng void main{ Complex c1(1,1), c2(2,3); Complex c3 = c1+c2; Complex c4(1.0,2.0), c5(3.0,5.0); Complex c6 = c4 + c5; }; Chương 5: Lập trình tổng qt © 2010 - KimThoa 13 Tham số khuôn mẫu Tham số khn mẫu kiểu (₫ể làm tham số mặc ₫ịnh) template class Array{ T data[N]; public: Tham số mặc định ố }; Sử dụng ụ g void main(){ Array a; Array b; Array c; } Chương 5: Lập trình tổng qt Giống © 2010 - KimThoa 14 Bài tập Xây dựng khuôn mẫu hàm cho phép tìm giá trị lớn nhất/hoặc nhỏ mảng Tổng quát hóa kiểu liệu cho lớp array, thực hàm thành viên cần thiết ₫ể — Khai báo khởi tạo giá trị ban ₫ầu — Hủy nhớ khơng cịn sử dụng — Thực phép toán +,-, +=, -=,… Chương 5: Lập trình tổng qt © 2010 - KimThoa 15 6.3 Thuật tốn tổng qt Ví dụ: viết hàm xếp phần tử mảng theo thứ tự từ nhỏ ₫ến lớn void sort(int *p, int n){ for(int i = 0; i < n-1; i++) for(int j = n-1; j > i; j) if(p[j] < p[j-1]) swap(p[j], p[j-1]); } void swap(int &a, int &b){ int t = a; a = b; b = t; } Chương 5: Lập trình tổng qt © 2010 - KimThoa 16 Tổng quát hóa kiểu liệu phần tử template void sort(T *p, int n){ for(int i = 0; i < n-1; i++) for(int j = n-1; j > i; j) if(p[j] < p[j 1]) p[j-1]) swap(p[j], p[j-1]); } void swap(T &a, T &b){ T t = a; a = b; b = t; } Thuật toán áp dụng cho nhiều kiểu liệu có ₫ịnh nghĩa phép so sánh nhỏ Int p[100]; sort(p,100); //OK char p2[100]; sort(p2,100); //OK complex p3[100]; sort(p3,100) //Lỗi, áp dụng lớp complex định //nghĩa phép so sánh nhỏ Chương 5: Lập trình tổng quát © 2010 - KimThoa 17 Câu hỏi: làm ₫ể ta xếp lại từ lớn ₫ến nhỏ mà không cần phải viết lại hàm Giải há G ả pháp: cho thêm tham biến vào khai báo hà h thê th b ế kh bá hàm enum comparetype {less, greater, abs_less, abs_greater}; template void sort(T *p, int n,comparetype c){ p, for(int i = 0; i < n-1; i++) for(int j = n-1; j > i; j) switch(c){ case less: if(p[j] < p[j 1]) p[j-1]) swap(p[j], p[j-1]); break; case greater: if(p[j] > p j (p j p[j-1]) ) swap(p[j], p[j-1]); break; case abs_less: if(abs(p[j]) < abs(p[j-1]) swap(p[j], p[j-1]); swap(p[j] p[j 1]); break; case abs_greater: if(abs(p[j]) > abs(p[j-1])) swap(p[j], p[j-1]); break; } } Chương 5: Lập trình tổng qt © 2010 - KimThoa 18 Nhược ₫iểm: — Hiệu không cao ệ q g — Tốc ₫ộ chậm — Khơng có tính mở: ví dụ muốn só sánh số phức theo phần thực khơng dùng ₫ược cách Giải pháp: tổng qt hóa phép tốn template p , p void sort(T *p, int n, Compare comp){ for(int i = 0; i < n-1; i++) for(int j = n-1; j > i; j) if(comp(p[j], p[j-1])) ( p(p[j], p[j ])) swap(p[j], p[j-1]); } Kiểu Compare — Một hàm — Một ₫ối tượng thuộc lớp có ₫ịnh nghĩa lại tốn tử gọi hàm Chương 5: Lập trình tổng quát © 2010 - KimThoa 19 Kiểu Compare hàm template inline bool less(const T &a, const T &b){ return a < b; //return operator b; //return operator>(a,b) } — Sử dụng int v[100]; double d[100]; sort(v,100,less); sort(d,100,greater) Chương 5: Lập trình tổng qt Một hàm © 2010 - KimThoa 20 — So sánh số phức template inline bool less_real(const complex &a, const complex &b){ return (a.get_real() > b.get_real()) //return operator>(a,b) } — Sử dụng co p e doub e c[ 00]; complex c[100]; Sort(c,100,less_real); Chương 5: Lập trình tổng quát © 2010 - KimThoa 21 Kiểu compare ₫ối tượng có ₫ịnh nghĩa lại tốn tử gọi hàm template struct Less { bool operator()(const T &a, const T &b){ return ab; } }; — Sử dụng int v[100]; double d[100]; sort(v,100,Less()); sort(d,100,Greater()) Chương 5: Lập trình tổng quát Một ₫ối tượng © 2010 - KimThoa 22 Bài tập Áp dụng tổng quát hóa kiểu liệu tổng qt hóa phép tốn ₫ể xây dựng hàm càn thiết thực phép toán cộng, trừ, nhân, chia phần tử hai mảng Sau ₫ó viết chương trình minh họa cách sử dụng Gợi ý: — Hàm thực phép toán template void operation(T *p1, T *p2, T *result,int n, OP op){ } — Định nghĩa phép toán theo dạng hàm template T add(const T &a, const T &b){ } — Hoặc ₫ịnh nghĩa phép toán theo dạng ₫ối tượng template struct Add{ }; Chương 5: Lập trình tổng qt © 2010 - KimThoa 23 Chương trình template void operation(T* p1, T* p2,T* result,int n, OP op){ for(int i = 0;i

Ngày đăng: 27/03/2014, 12:11

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan