Stl C++

  • June 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Stl C++ as PDF for free.

More details

  • Words: 2,316
  • Pages: 6
TÓM TẮT NỘI DUNG BÀI GIẢNG PHƯƠNG PHÁP LẬP TRÌNH HƯỚNG ðỐI TƯỢNG CHƯƠNG 5: Khuôn mẫu (Template) Chú ý: Tài liệu này chỉ nhằm mục ñích tóm tắt và hệ thống hóa lại các kiến thức ñã ñược giảng trên lớp. Các bạn nên tìm ñọc các tài liệu tham khảo ñã ñược lựa chọn cho mỗi phần ñược cung cấp trên website môn học: http://nuce.edu.vn/~giangnt/oop Mọi góp ý về nội dung của tài liệu này xin liên hệ với tôi theo ñịa chỉ email: [email protected]

Giảng viên: Nguyễn Trường Giang Bộ môn Kỹ thuật Hệ thống – Khoa Công nghệ Thông tin Trường ðại học Xây Dựng

1

Chương 5: Khuôn mẫu (Template) 1. ðặt vấn ñề: -

Khi viết chương trình, chúng ta luôn cần khả năng tạo ra một tập hợp các ñối tượng. Các ñối tượng này có thể cùng loại hoặc khác loại.

-

Ví dụ mảng, danh sách, hàng ñợi, ngăn xếp, v.v. ñều là tập hợp các ñối tượng. Chúng ñược xây dựng theo kiểu lớp chứa, tức là lớp mà ñược dùng ñể xây dựng tập hợp các ñối tượng.

-

Với các kỹ thuật ñã ñược tiếp cận từ ñầu chương trình tới nay, chúng ta chỉ có thể tạo ra một tập hợp các ñối tượng thuộc kiểu xác ñịnh trước. Nếu muốn tạo ra một tập hợp tương tự như vậy nhưng kiểu của phần tử khác ñi, chúng ta chỉ có cách chỉnh sửa chương trình nguồn.

-

 Cách làm như thế là không thuận tiện.

-

C++ cho phép ñịnh nghĩa ra một lớp “tổng quát”, kiểu của phần tử trở thành tham số. Khi cần sử dụng, chúng ta chỉ cần cung cấp kiểu cụ thể của tham số là có thể tạo ra lớp mới.

2. Khuôn mẫu lớp (class template) Lớp ma trận (Matrix) dưới dạng template: template class Matrix { public: Matrix (int i = 0, int j = 0) : r(i), c(j), a(new T(r*c)) {} Matrix( const Matrix& m) : a(0) { *this = m; } ~Matrix() { delete[] a; } int num_row() { return r; } int num_col() { return c; } Matrix& operator=( const Matrix& ); T& operator() ( int i, int j ); private: T *a; int r, c; };

Trong ñịnh nghĩa khuôn mẫu lớp lớp ở trên, chúng ta nhận thấy một số thay ñổi chính như sau: 1) Dòng ñầu tiên: template Cho biết lớp Matrix là một template chứ không phải là một lớp thông thường. Phần tham số template (tham số tổng quát) ñược chỉ ra bên trong cặp ký tự < >. Trong trường hợp này, chỉ có một tham số, tên là T. Từ khóa class: cho biết T là tham số kiểu (ñể phân biệt với tham số giá trị). Nó cho biết T là 1 kiểu, một kiểu bất kỳ nào ñó. (mặc dù có từ khóa class nhưng không nhất thiết T phải là một kiểu lớp, nó có thể là 1 kiểu “bình thường” ñược ñịnh nghĩa sẵn như int, char v.v.)

2

2) Thay về kiểu của phần tử, không phải double, int, hay một kiểu cụ thể nào mà kiểu khái quát T. Tóm lại, ñể khai báo một lớp template: template class C { ... // ••nh ngh•a c• th• c•a l•p C };

3. Tạo ra thể hiện của template: C Với: C: tên lớp, Tên_kiểu: là một kiểu bất kỳ Ví dụ: Matrix mi(5, 5); Matrix mc(4, 6); − Giải thích: Trình biên dịch sẽ tạo ra biến mi là một ma trận với các phần tử thuộc kiểu int; và tạo ra biến mc là một ma trận với các phần tử thuộc kiểu Complex (số phức); − ðiều xảy ra ở ñây là trình biên dịch sử dụng template Matrix ñể tạo ra 2 lớp thông thường, chúng ta nói rằng 2 thể hiện của lớp Matrix ñược tạo ra. Trong thể hiện thứ nhất, kiểu T ñược thay thế bằng kiểu int, còn trong thể hiện thứ 2, kiểu T ñược thay bằng kiểu Complex. − Biểu thức Matrix<X> (với X là một kiểu thông thường) sẽ là mới cho lớp mới ñược tạo ra. Tên lớp này ñược ñối xử như các tên lớp thông thường khác (tham số của hàm, khai báo biến của lớp này cũng ñược thực hiện như với các lớp thông thường khác). − Tên của khuôn mẫu lớp kết hợp với tên kiểu dữ liệu (ñược ñặt trong cặp dấu < >) sẽ tạo thành một kiểu dữ liệu, và ñược sử dụng giống như các kiểu dữ liệu khác. 4. Hàm thành phần của khuôn mẫu lớp Vì lớp là template nên hàm thành phần cũng phải là template. template // ••nh ngh•a hàm t/ph c•a l•p C KiểuTrảVề C::f(tham số) { ... // cài ñặt cụ thể của hàm thành phần }

− dòng template có ý nghĩa thông báo rằng sẽ có một template sắp ñược ñịnh nghĩa và tham số kiểu là T.

3

− Mỗi một thể hiện của lớp template sẽ có một tập các thể hiện của hàm thành phần, chúng ta phải viết ñầy ñủ C trước phần tên hàm ñể xác ñịnh rõ tên ñầy ñủ của hàm thành phần này. Chú ý: Tuy nhiên, bên trong phạm vi một lớp template, nếu cần sử dụng, ta chỉ cần viết tên lớp template này là ñủ, mà không cần phải viết cụ thể tên thể hiện của lớp. Tổng kết: khuôn mẫu lớp (class template) chưa phải là một lớp. Chỉ khi chúng ta cung cấp tham số kiểu cho lớp template chúng ta mới có một thể hiện của lớp template ñó; khi ñó chúng ta mới có một lớp ñược ñối xử như một lớp thông thường. 5.. Ví dụ về một số kiểu template: template

// Ki•u ph• bi•n: m•t tham s• ki•u.

template

// Hai tham s• ki•u.

template // M•t t/s• ki•u, m•t tham s• gtr•. template

// v•i m•t giá tr• ng•m ••nh.

template

// hàm làm tham s• cho template.

6. Các thành phần tĩnh -

Giống như các lớp thông thường khác, một lớp template cũng có thể chứa các thành phần dữ liệu tĩnh và hàm thành phần tĩnh.

-

Ví dụ: tạo ra biến tĩnh nm ñể ñếm số ma trận ñược tạo ra với mỗi kiểu; chúng ta tạo ra hàm thành phần tĩnh nmMatrix.

-

ðối với lớp thông thường, chúng ta biết rằng mỗi lớp sẽ chứa một thể hiện duy nhất của biến thành phần tĩnh. Các ñối tượng của lớp này sẽ chia sẻ một thành phần tĩnh này. Còn ñối với lớp template, mỗi thể hiện của lớp template có một phiên bản riêng của thành phần dữ liệu tĩnh.

-

Ví dụ: có 3 thể hiện của 1 lớp template (T, T, T<double>) thì sẽ có 3 phiên bản của biến tĩnh nm trong 3 thể hiện tương ứng của lớp Matrix ñó.

-

Hàm thành phần tĩnh: ñược ñịnh nghĩa giống như các hàm thành phần khác (là hàm thành phần không tĩnh).

-

Thành phần dữ liệu tĩnh cũng luôn phải ñược ñịnh nghĩa bên ngoài ñịnh nghĩa lớp, ñiều này cũng ñược áp dụng cho các lớp template.

-

Bởi vì sẽ có 1 phiên bản của thành phần dữ liệu tĩnh cho mỗi thể hiện của lớp template, do ñó phần ñịnh nghĩa của thành phần dữ liệu tĩnh cũng phải là một template, trước phần ñịnh nghĩa của nó sẽ có từ khóa template.

-

Việc gọi hàm thành phần tĩnh: Nhớ lại việc gọi hàm thành phần tĩnh trong lớp bình thường, chúng ta có 2 cách gọi: 1 là gọi hàm thông qua tên biến (ñối tượng), 2 là gọi hàm thông qua tên lớp. ðối với lớp template, ñể gọi 1 hàm thành phần tĩnh, thay vì sử dụng tên lớp, chúng ta sử dụng tên 1 thể hiện cụ thể của lớp ñó.

4

7. Tham số của template -

Trong các ví dụ trước ñây, chúng ta mới xét các template chỉ bao gồm một tham số (ñó là tham số về kiểu của dữ liệu bên trong lớp template). Tuy nhiên, một template có thể có số lượng tham số tùy ý. Các tham số ñó ñược chia làm hai nhóm: Tham số về kiểu & Tham số về giá trị. Tham số về kiểu ñược mở ñầu bằng từ khóa class, nó có thể nhận một kiểu bất kỳ. Tham số giá trị trông giống như tham số của hàm nhưng bị hạn chế là không thể nhận kiểu dữ liệu dấu phảy ñộng (bao gồm float, double,…)

-

Ví dụ: // array template #include template class array { T memblock [N]; public: void setmember (int x, T value); T getmember (int x); }; template array::setmember (int x, T value) { memblock[x]=value; } template T array::getmember (int x) { return memblock[x]; } int main () { array myints; array myfloats; myints.setmember (0,100); myfloats.setmember (3,3.1416); cout << myints.getmember(0) << '\n'; cout << myfloats.getmember(3) << '\n'; return 0; }

-

Tham số giá trị cũng có thể nhận giá trị ngầm ñịnh.

8. Việc tổ chức file cho lớp: − Với lớp template, phần ñịnh nghĩa lớp và ñịnh nghĩa của hàm thành phần nên ñược ñặt trong cùng một file (file tiêu ñề, hay header file). Nói chung, với mỗi lớp, chúng ta nên có hai file: một file tiêu ñề và một file chứa ñịnh nghĩa. Thêm vào ñó, chúng ta tổ chức theo cách: phần ñịnh nghĩa file ñặt trong file tiêu ñề, còn phần ñịnh nghĩa cụ thể của hàm thành phần nên ñặt trong file khác (file ñịnh nghĩa) [2]. − Từ góc nhìn của trình biên dịch, template không phải là hàm hay lớp thông thường. Chúng ñược biên dịch theo yêu cầu, có nghĩa là ñoạn code của một hàm template

5

không ñược biên dịch cho tới khi một có một lời giải thích rõ ràng ñược yêu cầu. Lúc ñó, trình biên dịch sinh ra một hàm cụ thể cho kiểu ñó từ template [1]. − Khi dự án phát triển, việc chia nhỏ code của một chương trình thành nhiều file khác nhau là bình thường, trong những trường hợp này, nói chung giao diện và cài ñặt cụ thể sẽ ñược tách riêng. Lấy ví dụ về một thư viện hàm, giao diện nói chung sẽ bao gồm phần khai báo của tất cả các hàm có thể dùng ñến. Nói chung, chúng ñược khai báo trong một file tiêu ñề (.h) còn phần cài ñặt cụ thể (phần ñịnh nghĩa của nhưng hàm này) ñược lưu trong file code C++ ñộc lập khác. − Chức năng giống như macro (giống thế nào?) của template ñặt giới hạn cho các dự án nhiều file: ðó là phần cài ñặt (hay ñịnh nghĩa) của một lớp hay một hàm template PHẢI ở trong cùng một file với phần khai báo. Có nghĩa là chúng ta không thể tách rời phần giao diện ra một file riêng, mà chúng ta phải gộp phần giao diện và cài ñặt vào cùng một file. − Trở lại ví dụ về thư viện hàm, nếu chúng ta muốn tạo ra một thư viện hàm template, thay vì tạo ra một file .h chúng ta nên tạo ra một file template chứa cả phần giao diện và phần cài ñặt của các template hàm. Việc gộp nhiều hơn một lần cùng một template với cả phần khai báo và phần ñịnh nghĩa trong một dự án không gây ra lỗi liên kết, bởi vì chúng ñược biên dịch theo yêu cầu; và trình biên dịch chấp nhận temlate nên ñược chuẩn bị ñể không sinh ra những ñoạn mã trùng nhau trong các trường hợp này. 9. Các ưu ñiểm của template: -

Template cho phép xây dựng các lớp tổng quát. Trình biên dịch có thể sinh ra nhiều lớp khác nhau dựa trên cùng một khuôn mẫu. Chúng ta không cần phải viết lại một lớp nào ñó.

-

Ví dụ: Nếu chúng ta có một template cho lớp List, trình biên dịch có thể giúp chúng ta tạo ra hai lớp List và List một cách nhanh chóng.

-

Bên cạnh việc áp dụng template cho lớp, chúng ta cũng có thể tạo ra các hàm tổng quát bằng cách viết template cho hàm. Với template này trình biên dịch tự ñộng tạo ra các hàm khác nhau ñể thao tác trên các ñối tượng khác nhau.

10. Template có phải là cách duy nhất ñể thực hiện công việc không? -

Người ta cũng có thể dùng tính thừa kế trong C++ ñể tạo ra các tập hợp khác nhau của các ñối tượng khác nhau. Khi ñó người ta cần dùng kết hợp thừa kế và ña thừa kế.

-

Tuy nhiên khó khăn khi sử dụng tính thừa kế trong trường hợp này là: cần phải xác ñịnh trước một lớp nào ñó sẽ ñược sử dụng như thế nào. Bên cạnh ñó, lập trình viên cũng cần xác ñịnh trước các lớp thừa kế ñược xây dựng như thế nào ñể biết ñược lớp mới cần kế thừa những thuộc tính nào. Các khó khăn này làm công việc của lập trình viên nặng nề hơn.

Kết luận: ñể xây dựng các tập hợp ñối tượng, sử dụng template sẽ thuận tiện hơn nhiều so với sử dụng tính thừa kế.

6

Related Documents

Stl C++
June 2020 3
Stl
April 2020 9
Stl-catalogue.pdf
June 2020 12
Stl Vector
April 2020 1
Stl Algorithms
November 2019 10
Stl Testing.pdf
June 2020 1