Bài giảng Ngôn ngữ lập trình C++: Phần 2 - TS. Nguyễn Duy Phương

159 3 0
Bài giảng Ngôn ngữ lập trình C++: Phần 2 - TS. Nguyễn Duy Phương

Đ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

Tiếp nội dung phần 1, Bài giảng Ngôn ngữ lập trình C++: Phần 2 cung cấp cho người học những kiến thức như: Tính kế thừa và đa hình; Một số lớp quan trọng; Thư viện STL và áp dụng. Mời các bạn cùng tham khảo!

HỌC VIỆN CƠNG NGHỆ BƯU CHÍNH VIỄN THƠNG KHOA CƠNG NGHỆ THÔNG TIN -   BÀI GIẢNG NGƠN NGỮ LẬP TRÌNH C++ Hiệu chỉnh : TS NGUYỄN DUY PHƯƠNG THS NGUYỄN MẠNH SƠN HÀ NỘI, 12/2020 CHƯƠNG TÍNH KẾ THỪA VÀ TÍNH ĐA HÌNH Nội dung chương tập trung trình bày vấn đề liên quan đến tính kế thừa tương ứng bội (đa hình) ngơn ngữ C++: Khái niệm kế thừa, dẫn xuất kiểu dẫn xuất Khai báo, định nghĩa hàm khởi tạo hàm hủy bỏ lớp dẫn xuất Truy nhập tới thành phần lớp sở lớp dẫn xuất Việc lớp kế thừa từ nhiều lớp sở khác Khai báo sử dụng lớp sở trừu tượng kế thừa Tính đa hình C++ 6.1 KHÁI NIỆM KẾ THỪA Lập trình hướng đối tượng có hai đặc trưng bản: Đóng gói liệu, thể cách dùng khái niệm lớp để biểu diễn đối tượng với thuộc tính private, cho phép bên ngồi truy nhập vào thông qua phương thức get/set Dùng lại mã, thể việc thừa kế lớp Việc thừa kế cho phép lớp thừa kế (gọi lớp dẫn xuất) sử dụng lại phương thức định nghĩa lớp gốc (gọi lớp sở) 6.1.1 Khai báo thừa kế Cú pháp khai báo lớp kế thừa từ lớp khác sau: class : { // Khai báo thành phần lớp }; Trong đó: Tên lớp dẫn xuất: tên lớp cho kế thừa từ lớp khác Tên lớp tuân thủ theo quy tắc đặt tên biến C++ Tên lớp cở sở: tên lớp định nghĩa trước lớp khác kế thừa Tên lớp tuân thủ theo quy tắc đặt tên biến C++ 132 Từ khóa dẫn xuất: từ khóa quy định tính chất kế thừa Có ba từ khóa dẫn xuất private, protected public Mục trình bày ý nghĩa từ khóa dẫn xuất Ví dụ: class Bus: public Car{ // Khai báo thành phần }; khai báo lớp Bus (xe buýt) kế thừa từ lớp Car (xe tơ) với tính chất kế thừa public 6.1.2 Tính chất dẫn xuất Sự kế thừa cho phép lớp dẫn xuất sử dụng lại số mã nguồn phương thức thuộc tính định nghĩa lớp sở Nghĩa lớp dẫn xuất truy nhập trực tiếp đến số thành phần lớp sở Tuy nhiên, phạm vi truy nhập từ lớp dẫn xuất đến lớp sở giống nhau: chúng quy định từ khóa dẫn xuất private, protected public Dẫn xuất private Dẫn xuất private quy định phạm vi truy nhập sau: Các thành phần private lớp sở khơng thể truy nhập từ lớp dẫn xuất Các thành phần protected lớp sở trở thành thành phần private lớp dẫn xuất Các thành phần public lớp sở trở thành thành phần private lớp dẫn xuất Phạm vi truy nhập từ bên vào lớp dẫn xuất tuân thủ quy tắc phạm vi lớp thông thường Dẫn xuất protected Dẫn xuất protected quy định phạm vi truy nhập sau: Các thành phần private lớp sở khơng thể truy nhập từ lớp dẫn xuất Các thành phần protected lớp sở trở thành thành phần protected lớp dẫn xuất Các thành phần public lớp sở trở thành thành phần protected lớp dẫn xuất Phạm vi truy nhập từ bên vào lớp dẫn xuất tuân thủ quy tắc phạm vi lớp thông thường 133 Dẫn xuất public Dẫn xuất public quy định phạm vi truy nhập sau: Các thành phần private lớp sở khơng thể truy nhập từ lớp dẫn xuất Các thành phần protected lớp sở trở thành thành phần protected lớp dẫn xuất Các thành phần public lớp sở thành phần public lớp dẫn xuất Phạm vi truy nhập từ bên vào lớp dẫn xuất tuân thủ quy tắc phạm vi lớp thông thường Bảng 6.1 tóm tắt lại quy tắc truy nhập quy định bới từ khóa dẫn xuất Kiểu dẫn xuất private protected public Tính chất lớp sở Tính chất lớp dẫn xuất private Không truy nhập protected private public private private Không truy nhập protected protected public protected private Không truy nhập protected protected public public 6.2 HÀM KHỞI TẠO VÀ HUỶ BỎ TRONG KẾ THỪA 6.2.1 Hàm khởi tạo kế thừa Khi khai báo đối tượng có kiểu lớp dẫn xuất từ lớp sở khác Chương trình tự động gọi tới hàm khởi tạo lớp dẫn xuất Tuy nhiên, thứ tự gọi hàm khởi tạo tương ứng lớp sở, sau đến hàm khởi tạo lớp dẫn xuất Do đó, thơng thường, hàm khởi tạo lớp dẫn xuất phải có hàm khởi tạo lớp sở Cú pháp khai báo hàm khởi tạo sau: ([]): ([]){ // Khởi tạo thuộc tính bổ sung lớp dẫn xuất 134 }; Vì tên hàm khởi tạo trùng với tên lớp, nên viết lại thành: ([]): ([]){ // Khởi tạo thuộc tính bổ sung lớp dẫn xuất }; Ví dụ: Bus():Car(){ // Khởi tạo thuộc tính bổ sung lớp Bus } định nghĩa hàm khởi tạo lớp Bus kế thừa từ lớp Car Định nghĩa thược phạm vi khai báo lớp Bus Đây hàm khởi tạo khơng tham số, gọi tới hàm khởi tạo không tham số lớp Car Lưu ý: Nếu định nghĩa hàm khởi tạo bên phạm vi lớp phải thêm tên lớp dẫn xuất toán tử phạm vi “::” trước tên hàm khởi tạo Giữa tên hàm khởi tạo lớp dẫn xuất hàm khởi tạo lớp sở, có mơt dấu hai chấm “:”, hai dấu “::” trở thành tốn tử phạm vi lớp Nếu khơng rõ hàm khởi tạo lớp sở sau dấu hai chấm “:” chương trình tự động gọi hàm khởi tạo ngầm định hàm khởi tạo khơng có tham số lớp sở hàm định nghĩa tường minh lớp sở Ví dụ, định nghĩa hàm khởi tạo: Bus():Car(){ // Khởi tạo thuộc tính bổ sung lớp Bus }; Có thể thay bằng: Bus(){ // Gọi hàm khởi tạo không tham số lớp Car // Khởi tạo thuộc tính bổ sung lớp Bus }; Chương trình 6.1 định nghĩa lớp Car có thuộc tính với hai hàm khởi tạo, sau định nghĩa lớp Bus có thêm thuộc tính label số hiệu tuyến xe buýt Lớp Bus cài đặt hai hàm khởi tạo tường minh, gọi đến hai hàm khởi tạo tương ứng lớp Car Chương trình 6.1 135 #include /* Định nghĩa lớp Car */ class Car{ int speed; char mark[20]; // Tốc độ // Nhãn hiệu float price; // Giá xe Car(); // Khởi tạo không tham số public: Car(int, char[], float); // Khởi tạo đủ tham số }; // Khởi tạo không tham số Car::Car(){ speed = 0; strcpy(mark, “”); price = 0; } // Khởi tạo đủ tham số Car::Car(int speedIn, char markIn[], float priceIn){ speed = speedIn; strcpy(mark, markIn); price = priceIn; } /* Định nghĩa lớp Bus kế thừa từ lớp Car */ class Bus: public Car{ int label; // Số hiệu tuyến xe Bus(); // Khởi tạo không tham số public: Bus(int, char[], float, int); // Khởi tạo đủ tham số }; // Khởi tạo không tham số Bus::Bus():Car(){ 136 label = 0; } // Khởi tạo đủ tham số Bus::Bus(int sIn, char mIn[], float pIn, int lIn):Car(sIn, mIn, pIn){ label = lIn; } Trong hàm khởi tạo lớp Bus, muốn khởi tạo thuộc tính lớp Car, ta phải khởi tạo gián tiếp thông qua hàm khởi tạo lớp Car mà gán giá trị trực tiếp cho thuộc tính speed, mark price Lí thuộc tính có tính chất private, nên lớp dẫn xuất truy nhập trực tiếp đến chúng 6.2.2 Hàm hủy bỏ kế thừa Khi đối tượng lớp dẫn xuất bị giải phóng khỏi nhớ, thứ tự gọi hàm hủy bỏ ngược với thứ tự gọi hàm thiết lập: gọi hàm hủy bỏ lớp dẫn xuất trước gọi hàm hủy bỏ lớp sở Vì lớp có nhiều hàm hủy bỏ, nên ta không cần phải hàm hủy bỏ lớp sở gọi sau hủy bỏ lớp dẫn xuất Do vậy, hàm hủy bỏ lớp dẫn xuất khai báo định nghĩa hoàn toàn giống với lớp thông thường: ::~([]){ … // giải phóng phần nhớ cấp phát cho thuộc tính bổ sung } Lưu ý: Hàm hủy bỏ lớp dẫn xuất giải phóng phần nhớ cấp phát động cho thuộc tính bổ sung lớp dẫn xuất, có, mà khơng giải phóng nhớ cấp cho thuộc tính lớp sở (phần hàm hủy bỏ lớp sở đảm nhiệm) Không phải gọi tường minh hàm hủy bỏ lớp sở hàm hủy bỏ lớp dẫn xuất Ngay lớp dẫn xuất không định nghĩa tường minh hàm hủy bỏ (do khơng cần thiết) mà lớp sở lại có định nghĩa tường minh Chương trình gọi hàm hủy bỏ ngầm định lớp dẫn xuất, sau gọi hàm hủy bỏ tường minh lớp sở Chương trình 6.2 cài đặt lớp Bus kế thừa từ lớp Car: lớp Car có thuộc tính có dạng trỏ nên cần giải phóng hàm hủy bỏ tường minh Lớp Bus có thêm thuộc tính có dạng trỏ danh sách đường phố mà xe buýt qua (mảng động chuỗi kí tự *char[]) nên cần giải phóng hàm hủy bỏ tường minh 137 Chương trình 6.2 #include /* Định nghĩa lớp Car */ class Car{ char *mark; // Nhãn hiệu xe public: ~Car(); // Hủy bỏ tường minh }; // Hủy bỏ tường minh Car::~Car(){ delete [] mark; } /* Định nghĩa lớp Bus kế thừa từ lớp Car */ class Bus: public Car{ char *voyage[]; // Hành trình tuyến xe ~Bus(); // Hủy bỏ tường minh public: }; Bus::~Bus(){ // Hủy bỏ tường minh delete [] voyage; } Trong hàm hủy bỏ lớp Bus, ta giải phóng vùng nhớ cấp phát cho thuộc tính voyage (hành trình xe bt), thuộc tính bổ sung thêm lớp Bus Mà khơng giải phóng vùng nhớ cấp phát cho thuộc tính mark (nhãn hiệu xe), việc thuộc trách nhiệm hàm hủy bỏ lớp Car thuộc tính mark khai báo lớp Car 6.3 TRUY NHẬP TỚI CÁC THÀNH PHẦN TRONG KẾ THỪA LỚP 6.3.1 Phạm vi truy nhập Mối quan hệ thành phần lớp sở lớp dẫn xuất quy định từ khóa dẫn xuất, trình bày mục 6.1.2, tóm tắt bảng 6.2 138 Kiểu dẫn xuất private protected public Tính chất lớp sở Tính chất lớp dẫn xuất private Khơng truy nhập protected private public private private Không truy nhập protected protected public protected private Không truy nhập protected protected public public Ta xét phạm vi truy nhập theo hai loại: Phạm vi truy nhập từ hàm bạn, lớp bạn lớp dẫn xuất Phạm vi truy nhập từ đối tượng có kiểu lớp dẫn xuất Truy nhập từ hàm bạn lớp bạn lớp dẫn xuất Nhìn vào bảng tổng kết 6.2, phạm vi truy nhập hàm bạn, lớp bạn lớp dẫn xuất vào lớp sở sau: Với dẫn xuất private, hàm bạn truy nhập thành phần protected public lớp sở chúng trở thành thành phần private lớp dẫn xuất, truy nhập từ hàm bạn Với dẫn xuất protected, hàm bạn truy nhập thành phần protected public lớp sở chúng trở thành thành phần protected lớp dẫn xuất, truy nhập từ hàm bạn Với dẫn xuất public, hàm bạn truy nhập thành phần protected public lớp sở chúng trở thành thành phần protected public lớp dẫn xuất, truy nhập từ hàm bạn Đối với ba loại dẫn xuất, hàm bạn không truy nhập thành phần private lớp sở, thành phần không truy nhập từ lớp dẫn xuất Truy nhập từ đối tượng tạo lớp dẫn xuất Nhìn vào bảng tổng kết 6.2, phạm vi truy nhập đối tượng lớp dẫn xuất vào lớp sở sau: 139 Với dẫn xuất private, đối tượng lớp dẫn xuất không truy nhập thành phần lớp sở chúng trở thành thành phần private lớp dẫn xuất, khơng truy nhập từ bên ngồi Với dẫn xuất protected, đối tượng lớp dẫn xuất không truy nhập thành phần lớp sở chúng trở thành thành phần protected lớp dẫn xuất, khơng truy nhập từ bên ngồi Với dẫn xuất public, đối tượng lớp dẫn xuất truy nhập thành phần public lớp sở chúng trở thành thành phần public lớp dẫn xuất, truy nhập từ bên Bảng 6.3 tổng kết phạm vi truy nhập từ hàm bạn đối tượng lớp dẫn xuất vào thành phần lớp sở, quy định từ khóa dẫn xuất Kiểu dẫn xuất private protected public Tính chất lớp sở Tính chất lớp dẫn xuất Truy nhập từ hàm bạn lớp dẫn xuất Truy nhập từ đối tượng lớp dẫn xuất private - - - protected private ok - public private ok - private - - - protected protected ok - public protected ok - private - - - protected protected ok - public public ok ok 6.3.2 Sử dụng thành phần lớp sở từ lớp dẫn xuất Từ bảng tổng kết phạm vi truy nhập, ta thấy có dẫn xuất theo kiểu public đối tượng lớp dẫn xuất truy nhập đến thành phần (thuộc loại public) lớp sở Khi đó, việc gọi đến thành phần lớp sở tương tự gọi thành phần lớp thông thường: Đối với biến đối tượng thông thường: .([Các đối số]); Đối với trỏ đối tượng: ->([Các đối số]); 140  Đưa dãy lớn bao gồm số Fibonacci test theo dòng Input 10 13 13 23 Output 13 13 MÃ BÀI: CPPLAN01 TIÊU ĐỀ: Large Number ĐỘ KHÓ: CHỦ ĐỀ: Bài tập tổng hợp - CHỦ ĐỀ CON Kiểu liệu phép toán NỘI DUNG: Cho hai số lớn X Y biểu diễn hai xâu ký tự Nhiệm vụ bạn tìm |X-Y|? Input:  Dòng đưa vào số lượng test T  Những dòng đưa vào test Mỗi test gồm hai dòng: dòng thứ đưa xâu X; dòng đưa vào xâu Y  T, X, Y thỏa mãn ràng buộc : 1≤T≤100; 0≤length(X), length(Y)≤103 Output:  Đưa số kết test theo dòng Input: 978 12977 100 1000000 Output: 11999 0999900 MÃ BÀI: CPPLAN02 TIÊU ĐỀ: Large Number ĐỘ KHÓ: CHỦ ĐỀ: Bài tập tổng hợp - CHỦ ĐỀ CON Kiểu liệu phép toán NỘI DUNG: Cho hai số lớn X Y biểu diễn hai xâu ký tự Nhiệm vụ bạn tìm X+Y? Input:  Dịng đưa vào số lượng test T  Những dòng đưa vào test Mỗi test gồm hai dòng: dòng thứ đưa xâu X; dòng đưa vào xâu Y  T, X, Y thỏa mãn ràng buộc : 1≤T≤100; 0≤length(X), length(Y)≤103 275 Output:  Đưa số kết test theo dòng Input: 12 198111 Output: 198123 MÃ BÀI: CPPLAN03 TIÊU ĐỀ: Large Number ĐỘ KHÓ: CHỦ ĐỀ: Bài tập tổng hợp - CHỦ ĐỀ CON Kiểu liệu phép toán NỘI DUNG: Cho hai số lớn X Y biểu diễn hai xâu ký tự Nhiệm vụ bạn tìm X × Y? Input:  Dòng đưa vào số lượng test T  Những dòng đưa vào test Mỗi test gồm hai dòng: dòng thứ đưa xâu X; dòng đưa vào xâu Y  T, X, Y thỏa mãn ràng buộc : 1≤T≤100; 0≤length(X), length(Y)≤103 Output:  Đưa số kết test theo dòng Input: Output: MÃ BÀI: CPPLAS01 TIÊU ĐỀ: Chữ số cuối ĐỘ KHÓ: CHỦ ĐỀ: Bài tập tổng hợp - CHỦ ĐỀ CON Số học NỘI DUNG: Thấy Tí thích thú với số, giáo giao cho Tí tập rút gọn số Phép rút gọn thực sau: từ số ban đầu, số tạo thành cách cộng chữ số số ban đầu với Sau Tí phải thực tiếp tục với số vừa thu Quá trình rút gọn kết thúc số thu có chữ số Các bạn Tí tìm chữ số cuối phép rút gọn! Input Dòng gồm số lượng test T (T

Ngày đăng: 01/03/2022, 09:42

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

Tài liệu liên quan