Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 20 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
20
Dung lượng
545,55 KB
Nội dung
Chapter 11: Lập trình khái quát (Generic programming) EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Khuôn mẫu hàm (Function templates) EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội General Đôi ta muốn viết lần tạo hàm với tham số thuộc nhiều kiểu khác nhau, thay phải viết chồng nhiều hàm tương tự int max(int a, int b) { return a>b ? a:b; } double max(double a, double b) { return a>b ? a:b; } float max(float a, float b) { return a>b ? a:b; } lập trình mức độ khái quát cao hơn: coi kiểu biến tham số (type parameterization) Khuôn mẫu hàm (function template): khái niệm giúp định nghĩa hàm mà chưa xác định kiểu tham số Có thể hiểu viết gộp chung hàm chồng giống mặt thuật toán Kiểu tham số tham số khn mẫu EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Định nghĩa hàm khái quát Ví dụ 1: template void swap(T& a, T& b) { T c = a; a = b; b = c; } T giả định kiểu tham số a, b biến c T xác định gọi hàm T tham số khuôn mẫu, a, b tham số hàm Ví dụ 2: template void push(Containter& s, Object o) { } Có thể dùng từ khố “class” thay “typename” template void swap(T& a, T& b) { } EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Gọi hàm khái quát Gọi với kiểu tường minh: max(a, b); max(x, y); swap(s1, s2); swap(p1, p2); push(l, st); Gọi với kiểu ngầm định: int a, double max(a, max(x, max(a, b; x, y; b); // max(a, b); y); // max(x, y); x); // lỗi EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Chồng hàm khái qt Các khn mẫu hàm định nghĩa chồng template T max(T a, T b) { } template T max(T a, T b, T c) { } template T max(T* arr, int n) { } Gọi hàm chồng max(10, 20); max('c', 'f'); max(1.5, 2.1, 3.14); max("1un34k", 6); EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Cá biệt hoá hàm khái quát Có thể định nghĩa phiên cho trường hợp riêng hàm khái quát template T max(T a, T b) { return a>b ? a:b; } template const char* max(const char* s1, const char* s2) { return strcmp(s1, s2) == ? s1:s2; } Cá biệt hố khơng hồn tồn template void push(Containter& s, Object o) { } template void push(Stack& s, Object o) { } EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Khơng khái qt hố kiểu tham số… Khái quát hoá kiểu trả template Product makeProd(Worker& w) { w.work(); return w.getResult(); } Khái quát hoá kiểu biến cục template void forEach(const List& l) { Iterator i = l.first(); for (; i!=l.last(); i = i.next()) doSmth(i.get()); } EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Tham số khuôn mẫu không kiểu Có thể giá trị sử dụng giá trị template Object* makeArray() { return new Object[N]; } string* p1 = makeArray(); SinhVien* p2 = makeArray(); Cả giá trị kiểu tham số template T range(T t) { return tmax ? max : t); } y = range(x); b = range(a); EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Lưu ý dùng hàm khái quát Phần thực thi khuôn mẫu hàm thực biên dịch có thơng tin kiểu viết khn mẫu hàm thư viện nguyên mẫu phần thực thi hàm viết file h (có thể viết riêng phần thực thi file khác include vào file h) Khi sử dụng tham số thuộc kiểu trình biên dịch sinh hàm tương ứng với kiểu tham số int a = 10, b = 20; swap(a, b); // sinh ra: void swap(int&, int&) { } swap(x, y); // void swap(float&, float&) { } Có thể dùng trường hợp cụ thể phát sinh lỗi cú pháp template T divide(T a, T b) { return a/b; } double z = divide(1.5, 0.5); // OK const char* c = divide("ssss", "dddd"); 10 // lỗi EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Khuôn mẫu lớp (Class templates) 11 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Khái niệm Tương tự với hàm, lớp khái qt hố khn mẫu lớp Lớp khai báo sử dụng kiểu chưa xác định tham số hoá 12 template class Array { private: int N; Object* p; public: void setAt(int i, Object o) { } Object& operator[](int i) { } }; EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Phương thức bên ngồi khn mẫu lớp template class Array { private: int N; Object* p; public: Array(int N); ~Array(); void setAt(int i, Object o); int length() const; Object& operator[](int i); }; template Array::~Array() { delete[] p; } template Array::Array(int N) { this->N = N; p = new Object[N]; } template Object& Array:: operator[](int i) { return p[i]; } template void Array:: setAt(int i, Object o) { p[i] = o; } template int Array::length() const { return N; } Các phương thức khai báo tương tự khuôn mẫu hàm 13 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS Đào Trung Kiên – ĐH Bách khoa Hà Nội Sử dụng đối tượng lớp khái quát Ví dụ: Array a(10); for (int i=0; i