Giáo trình lập trình nâng cao - Bài 7: Hàm kiến tạo và các công cụ khác - Hoàng Thị Điệp
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình lập trình nâng cao - Bài 7: Hàm kiến tạo và các công cụ khác - Hoàng Thị Điệp", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- giao_trinh_lap_trinh_nang_cao_bai_7_ham_kien_tao_va_cac_cong.pdf
Nội dung text: Giáo trình lập trình nâng cao - Bài 7: Hàm kiến tạo và các công cụ khác - Hoàng Thị Điệp
- Bài 7: Hàm kiến tạo và các công cụ khác Giảng viên: Hoàng Thị Điệp Khoa Công nghệ Thông tin – ĐH Công Nghệ
- Chapter 7 Constructors and Other Tools Copyright © 2010 Pearson Addison-Wesley. All rights reserved
- Mục tiêu bài học • Hàm kiến tạo – Định nghĩa – Cách gọi • Một số công cụ – Từ khóa const cho tham số – Hàm inline – Thành viên dữ liệu static • vector – Giới thiệu lớp vector DTH INT2202
- Hàm kiến tạo • Khởi tạo đối tượng – Khởi tạo một vài hay tất cả các biến thành viên – Có thể thực hiện thêm các công việc khác • Một kiểu hàm thành viên đặc biệt – Được gọi tự động khi một đối tượng được khai báo • Công cụ rất hữu ích – Nguyên lý chính của LTHĐT DTH INT2202
- Định nghĩa hàm kiến tạo • Hàm kiến tạo được định nghĩa giống như các hàm thành viên khác – Ngoại trừ: 1. Nó phải có tên giống hệt tên lớp 2. Không thể trả về một giá trị; kể cả void! DTH INT2202
- Ví dụ định nghĩa hàm kiến tạo • Định nghĩa lớp với hàm kiến tạo: class DayOfYear { public: DayOfYear(int monthValue, int dayValue); //Hàm kiến tạo khởi tạo month & day void input(); void output(); private: int month; int day; } DTH INT2202
- Lưu ý về hàm kiến tạo • Tên của hàm kiến tạo: DayOfYear – Trùng tên lớp • Trong khai báo hàm kiến tạo không chỉ định kiểu trả về – Kể cả là kiểu void • Hàm kiến tạo nằm trong vùng public – Nó được gọi mỗi khi một đối tượng được khai báo – Nếu private, sẽ không thể khai báo được đối tượng. DTH INT2202
- Gọi tới hàm kiến tạo • Khai báo đối tượng: DayOfYear date1(7, 4), date2(5, 5); • Các đối tượng sẽ được tạo ra ở đây. – Hàm kiến tạo được gọi – Các giá trị trong cặp ngoặc tròn được truyền làm số của hàm kiến tạo – Các biến thành viên month, day được khởi tạo: date1.month 7 date2.month 5 date1.day 4 date2.day 5 DTH INT2202
- Thử lời gọi tương đương • Xét: DayOfYear date1, date2 date1.DayOfYear(7, 4); // không hợp lệ! date2.DayOfYear(5, 5); // không hợp lệ! • Có vẻ là ổn – KHÔNG thể gọi tới hàm kiến tạo như cách bạn vẫn gọi tới các hàm thành viên! DTH INT2202
- Mã nguồn hàm kiến tạo • Định nghĩa hàm kiến tạo cũng giống định nghĩa các hàm thành viên khác: DayOfYear::DayOfYear(int monthValue, int dayValue) { month = monthValue; day = dayValue; } • Chú ý 2 tên giống nhau ở 2 bên :: – Nhận diện rõ ràng một hàm kiến tạo • Chú ý không có kiểu trả về – Nhất quán với định nghĩa lớp DTH INT2202
- Một cách định nghĩa khác • Định nghĩa lúc trước tương đương với: DayOfYear::DayOfYear(int monthValue, int dayValue) : month(monthValue), day(dayValue) { } • Dòng trỏ bởi mũi tên gọi là “vùng khởi tạo” • Thân của hàm này rỗng • Cách định nghĩa này được khuyến khích dùng hơn DTH INT2202
- Mục đích gia tăng của hàm kiến tạo • Không chỉ nhằm khởi tạo dữ liệu • Thân hàm không nhất thiết phải rỗng • Mà còn nhằm kiểm tra tính hợp lệ của dữ liệu – Đảm bảo chỉ những dữ liệu hợp lý mới được gán cho biến thành viên của lớp – Nguyên lý quan trọng LTHĐT DTH INT2202
- Nạp chồng hàm kiến tạo • Có thể nạp chồng hàm kiến tạo như làm với các hàm khác • Nhắc lại: chữ kí của hàm bao gồm – tên hàm – danh sách tham số • Nên cung cấp hàm kiến tạo cho tất cả các danh sách đối số có thể – Cụ thể là “bao nhiêu” đối số DTH INT2202
- Ví dụ lớp có hàm kiến tạo: Display 7.1 Lớp có hàm kiến tạo (1/3) DTH INT2202
- Ví dụ lớp có hàm kiến tạo: Display 7.1 Lớp có hàm kiến tạo (2/3) DTH INT2202
- Ví dụ lớp có hàm kiến tạo: Display 7.1 Lớp có hàm kiến tạo (3/3) DTH INT2202
- Hàm kiến tạo không đối số • Có thể gây nhầm lẫn • Một hàm không đối số chuẩn: – Được gọi với cú pháp: callMyFunction(); • Cặp ngoặc tròn rỗng bên trong • Ứng với lệnh khai báo đối tượng mà chỉ định giá trị khởi tạo: – DayOfYear date1; // Gọi hàm kiến tạo! – DayOfYear date(); // Không gọi hàm kiến tạo! • Điều gì thực sự diễn ra? • Trình biên dịch coi đây là một khai báo/nguyên mẫu hàm! • Hãy nhìn kĩ cấu trúc của dòng lệnh này! DTH INT2202
- Gọi tường minh tới hàm kiến tạo • Có thể gọi tới hàm kiến tạo một lần nữa – Sau khi khai báo đối tượng • Nhắc lại: hàm kiến tạo được gọi tự động khi được khai báo – Có thể gọi thông qua tên đối tượng; lời gọi chuẩn tới hàm thành viên • Cho ta một cách tiện lợi để lập giá trị các biến thành viên • Cách này khá khác cách gọi chuẩn tới hàm thành viên DTH INT2202
- Ví dụ gọi tường minh tới hàm kiến tạo • Lời gọi như vậy sẽ trả về “một đối tượng vô danh” – sau đó có thể dùng nó trong phép gán – Hành động: DayOfYear holiday(7, 4); • Hàm kiến tạo được gọi khi khai báo đối tượng • Bây giờ ta sẽ “khởi tạo lại” : holiday = DayOfYear(5, 5); – Gọi tường minh tới hàm kiến tạo – Trả về một “đối tượng vô danh” mới – Gán nó cho đối tượng hiện thời DTH INT2202
- Hàm kiến tạo mặc định • Được định nghĩa là: hàm kiến tạo không đối số • Nên luôn có một hàm như vậy • Sinh tự động? – Có và Không – Nếu không có bất cứ hàm kiến tạo nào được định nghĩa Có – Nếu có hàm kiến tạo nào đó đã được định nghĩa Không • Nếu không có hàm kiến tạo mặc định: – Không thể khai báo: MyClass myObject; • Không có giá trị khởi tạo đi kèm DTH INT2202
- Biến thành viên có kiểu định nghĩa bởi lớp • Biến thành viên có thể thuộc bất cứ kiểu nào – Kể cả là đối tượng của lớp khác! – Kiểu quan hệ giữa các lớp • Nguyên lý quan trọng của LTHĐT • Cần kí hiệu đặc biệt cho hàm kiến tạo – Để chúng có thể gọi “ngược” tới hàm kiến tạo của đối tượng thành viên DTH INT2202
- Ví dụ biến thành viên có kiểu class Display 7.3 Biến thành viên có kiểu class (1/5) DTH INT2202
- Ví dụ biến thành viên có kiểu class Display 7.3 Biến thành viên có kiểu class (2/5) DTH INT2202
- Ví dụ biến thành viên có kiểu class Display 7.3 Biến thành viên có kiểu class (3/5) DTH INT2202
- Ví dụ biến thành viên có kiểu class Display 7.3 Biến thành viên có kiểu class (4/5) DTH INT2202
- Ví dụ biến thành viên có kiểu class Display 7.3 Biến thành viên có kiểu class (5/5) DTH INT2202
- Cách truyền tham số • Hiệu quả của việc truyền tham số – Truyền giá trị • Cần sao đối số Sinh “chi phí” – Truyền tham chiếu • Chỗ đặt trước cho đối số thực sự • Là cách hiệu quả nhất – Khác biệt này là không đáng kể với kiểu dữ liệu đơn – Với kiểu định nghĩa bởi lớp lợi thế rõ ràng • Truyền tham chiếu được khuyến khích dùng – Đặc biệt cho dữ liệu “lớn” như kiểu định nghĩa bởi lớp DTH INT2202
- Từ khóa const cho tham số • Kiểu dữ liệu lớn (thường là kiểu định nghĩa bởi lớp) – Được khuyên là nên dùng truyền tham chiếu – Ngay cả khi hàm không biến đổi đối số • Bảo vệ đối số – Dùng tham số hằng • Còn được gọi là tham số tham chiếu hằng – Đặt từ khóa const trước kiểu dữ liệu – Giới hạn tham số ở mức “chỉ đọc” – Nếu cố biến đổi tham số sẽ sinh lỗi biên dịch DTH INT2202
- Việc dùng từ khóa const • Hoặc là tất cả hoặc không gì cả • Nếu hàm không cần biến đổi dữ liệu – Bảo vệ tham số bằng const – Bảo vệ TẤT CẢ các tham số như vậy • Điều này cũng áp dụng với tham số của hàm thành viên DTH INT2202
- Hàm inline • Hàm không phải thành viên: – Dùng từ khóa inline trong khai báo hàm và dòng đầu định nghĩa hàm • Hàm thành viên: – Đặt mã định nghĩa hàm BÊN TRONG định nghĩa lớp tự động inline • Chỉ dùng cho những hàm rất ngắn • Mã thực sự sẽ được chèn vào nơi gọi – Bớt “chi phí” gọi hàm – Hiệu quả hơn, nhưng chỉ với hàm ngắn! DTH INT2202
- Hàm thành viên inline • Định nghĩa hàm thành viên – Thường thì các định nghĩa được tách ra 1 tệp riêng – Có thể định nghĩa BÊN TRONG định nghĩa lớp • Khiến hàm này thành "in-line" • Nhắc lại: chỉ dùng với những hàm rất ngắn • Tính hiệu quả – Nếu quá dài thật ra lại kém hiệu quả! DTH INT2202
- Thành viên static • Biến thành viên static – Tất cả các đối tượng của lớp “dùng chung” một bản sao – Một đối tượng biến đổi nó tất cả sẽ chịu tác động • Hữu ích cho việc “theo dõi” – Một hàm thành viên được gọi bao nhiêu lần – Có bao nhiêu đối tượng đang tồn tại • Trong khai báo, đặt từ khóa static trước kiểu DTH INT2202
- Hàm static • Hàm thành viên có thể là static – Nếu không cần truy cập đến dữ liệu của đối tượng – Và vẫn “phải” là thành viên của lớp – Thì chỉ định nó là một hàm static • Có thể được gọi từ bên ngoài lớp – Không qua đối tượng của lớp: • Ví dụ: Server::getTurn(); – Thông qua đối tượng của lớp • Cách chuẩn: myObject.getTurn(); • Chỉ có thể sử dụng dữ liệu/hàm static! DTH INT2202
- Ví dụ thành viên static: Display 7.6 Thành viên static (1/4) DTH INT2202
- Ví dụ thành viên static: Display 7.6 Thành viên static (2/4) DTH INT2202
- Ví dụ thành viên static: Display 7.6 Thành viên static (3/4) DTH INT2202
- Ví dụ thành viên static: Display 7.6 Thành viên static (4/4) DTH INT2202
- vector • Giới thiệu vector – Nhắc lại: mảng tĩnh có kích thước không đổi – vector: “là kiểu mảng có kích thước thay đổi” • trong quá trình thực thi chương trình – Định nghĩa trong Thư Viện Khuôn Mẫu Chuẩn - Standard Template Library (STL) • Dùng template lớp DTH INT2202
- Căn bản về vector • Tương tự như mảng: – Có kiểu cơ sở cho từng phần tử – Lưu một tập các giá trị cùng thuộc kiểu cơ sở • Nhưng cách khai báo thì khác: – Cú pháp: vector • Là dấu hiệu khuôn mẫu lớp • Bất cứ kiểu dữ liệu nào cũng có thể đặt vào vị trí Kiểu_Cơ_Sở • Tạo ra lớp vector “mới” cho kiểu cơ sở được chỉ định – Ví dụ khai báo: vector v; so sanh voi int a[100]; DTH INT2202
- Sử dụng vector • vector v; – "v là vector kiểu int" – Gọi tới hàm kiến tạo mặc định • tạo ra đối tượng vector rỗng • Đánh chỉ số để truy cập giống như mảng • Nhưng để thêm phần tử: – Phải gọi tới hàm thành viên push_back • Hàm thành viên size() – Trả về số phần tử hiện thời DTH INT2202
- Ví dụ vector: Display 7.7 Sử dụng 1 vector (1/2) DTH INT2202
- Ví dụ vector: Display 7.7 Sử dụng 1 vector (2/2) DTH INT2202
- Tính hiệu quả của vector • Hàm thành viên capacity() – Trả về dung lượng nhớ đã cấp phát cho đối tượng – Không giống size() – Thường thì capacity > size • Tự động tăng khi cần • Nếu quan tâm đến tính hiệu quả: – Có thể thiết lập cách xử lý dung lượng thủ công • v.reserve(32); //đặt capacity bằng 32 • v.reserve(v.size()+10); // đặt capacity bằng 10 cộng với size DTH INT2202
- Tóm tắt 1 • Hàm kiến tạo: tự động khởi tạo dữ liệu của lớp – Được gọi khi khai báo đối tượng – Hàm kiến tạo trùng tên với lớp • Hàm kiến tạo mặc định không có đối số – Nên luôn định nghĩa • Biến thành viên của lớp – Có thể là đối tượng của một lớp khác • Cần có phần khởi tạo trong hàm kiến tạo DTH INT2202
- Tóm tắt 2 • Tham số tham chiếu hằng – Hiệu quả hơn truyền giá trị • Có thể viết inline những hàm rất ngắn – Có thể cải thiện hiệu quả • Biến thành viên static – Được dùng chung bởi tất cả các đối tượng của lớp • Các lớp vector – Giống như: “mảng có thể lớn lên hay nhỏ đi" DTH INT2202
- Chuẩn bị bài tới • Đọc chương 8 giáo trình: Nạp chồng toán tử, Từ khóa friend và Tham chiếu DTH INT2202