Lập trình hướng đối tượng với C++
- C++ là một sựmởi rộng của C, do đó có thểsửdụng một chương trình biên dịch
C++ đểdịch và thực hiện các chương trình viết bằng C
- C yêu cầu các chú thích nằm giữa /* và */. C++ cho phép tạo một chú thích bắt đầu
bằng “//” cho đến hết dòng
- C++ cho phép khai báo tuỳý. Thậm chí có thểkhai báo biến trong phần khởi tạo
của câu lênh lặp for
- C++ cho phép truyền tham sốcho hàm bằng tham chiếu. Điều này tương tựnhư
truyền tham biến cho chương trình con trong ngôn ngữlập trình PASCAL. Trong lời gọi
hàm ta dùng tên biến và biến đó sẽ được truyền cho hàm qua tham chiếu. Điều đó cho
phép thao tác trực tiếp trên biến được truyền chứkhông phải gián tiếp qua biến trỏ.
- Toán tửnew và delete trong C++ được dùng đểquản lý bộnhớ động thay vì các
hàm cấp phát động của C
- C++ cho phép người viết chương trình mô tảcác giá trịngầm định cho các tham số
của hàm, nhờ đó hàm có thể được gọi với một danh sách các tham sốkhông đủ.
- Toán tử“::” cho phép truy nhập biến toàn cục khi đồng thời sửdụng biến cục bộvà
toàn cục cùng tên.
- Có thể định nghĩa các hàm cùng tên với các tham sốkhác nhau. Hai hàm cùng tên
sẽ được phân biệt nhờgiá trịtrảvềvà danh sách kiểu các tham số
+= S2; cout << S1 << endl; cout << "S1 += \" to you\" yields" << endl; S1 += " to you"; cout << "S1 = " << S1 << endl; cout << "The substring of S1 starting at" << endl << "location 0 for 14 characters, S1(0, 14), is: " << S1(0, 14) << endl; cout << "The substring of S1 starting at" << endl << "location 15, S1(15, 0), is: " << S1(15, 0) <<endl; // 0 is "to end of string" String *S4Ptr = new String(S1); cout << "*S4Ptr = " << *S4Ptr <<endl; cout << "assigning *S4Ptr to *S4Ptr" << endl; *S4Ptr = *S4Ptr; cout << "*S4Ptr = " << *S4Ptr << endl; delete S4Ptr; S1[0] = 'H'; S1[6] = 'B'; cout <<"S1 after S1[0] = 'H' and S1[6] = 'B' is: "<< S1 << endl; cout << "Attempt to assign 'd' to S1[30] yields:" << endl; S1[30] = 'd'; //Loi: Chi so vuot khoi mien!!! return 0; } 28. kết quả LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++ Trang 46 D/ BÀI TẬP TỰ GIẢI Câu hỏi trắc nghiệm Câu 1: Định nghĩa nào đúng cho toán tử nhập(>>) của một lớp T a) istream& operator>>(istream&); b) istream& operator>>(istream); c) friend istream& operator>>(istream&, T&); d) friend istream& operator>>(istream&, T); LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++ Trang 47 Câu 2 Định nghĩa nào phù hợp nhất cho toán tử lấy thành phần([]) của lớp mảng A a) int operator [] (int) b) int& operator [] (int) c) friend int operator [] (A&, int) d) friend int& operator [] (A&, int) Câu 3: Chỉ ra cách định nghĩa toán tử cho lớp T bị sai a) T operator-(T&) b) T operator-() c) T operator-() d) friend T opreator +(T&); e) T operator +(T&); Câu 4: Chỉ ra cách định nghĩa toán tử cho lớp T bíai a) T& operator ++() b) T operator ++(); c) T& operator++(int); d) T&operator++(float) Câu 5: Cho lớp A class A { public: operator int (); }; A a; int i=a;(1) float f=a;(2) Chỉ ra dòng nào có lỗi a) Chỉ dòng 1 lỗi b) Chỉ dòng 2 lỗi c) Cả hai dòng đều lỗi d) Không dòng nào lỗi Bài tâp Bài 1: Tạo kiểu dữ liệu Date biểu diễn ngày, tháng, năm. Cài đặt các toán tử để tính một ngày trước hoặc sau một ngày xác định nào đó, tính khoảng cách thao ngày giữa hai ngày xác định, tính thứ trong tuần của ngày. Các toán tử vào ra cho ngày. Bài 2: Để lưu trữ một ma trận đối xứng thì không cần đủ ô nhớ cho tất cả các phần tử của nó. Xây dựng lớp biểu diễn ma trận đối xứng có các toán tử truy nhập từng phần tử của ma trận. Chỉ sử dụng đủ lượng bộ nhớ cần thiết để lưu ma trận đối xứng Bài 3 Xây dựng lớp biểu diễn các đa thức với các toán tử cộng, trừ, nhân, chia và đảo dấu. Định nghĩa toán tử xuất để kết xuất. Bài 4: Xây dựng một lớp map cho phép biểu diễn một ánh xạ từ một chuỗi kí tự thành một giá trị số nguyên. Định nghĩa toán tử [] cho lớp để có thể sử dụng ánh xạ theo cách như [“abc”]->5 LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++ Trang 48 Bài 5 Xây dựng một lớp biểu diễn các vector n chiều với các toán tử cộng, trừ, tích có hướng hai vector và tích vô hướng một vector với một số thực. Định nghĩa toán tử cho phép truy nhập các thành phần của vector. LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++ Trang 49 Kü thuËt thõa kÕ MỤC TIÊU CỦA BÀI NÀY GIÚP NGƯỜI HỌC Cài đặt được sự thừa kế Sử dụng các thành phần của lớp cơ sở Định nghĩa lại các hàm thành phần Truyền thông tin giữa các hàm thiết lập của lớp dẫn xuất và lớp cơ sở Các loại dẫn xuất khác nhau và sự thay đổi trạng thái của các thành phần lớp cơ sở. Sự tương thích giữa các đối tượng của lớp dẫn xuất và lớp cơ sở Toán tử gán và thừa kế Hàm ảo và tính đa hình A/ NHẮC LẠI LÝ THUYẾT Thừa kế nâng cao khả năng sử dụng lại của các đoạn mã chương trình. Người lập trình có thể khai báo lớp mới thừa thừa kế dữ liệu và hàm thành phần từ lớp cơ sở đã được định nghĩa trước đó. Ta gọi lớp mới là lớp dẫn xuất. Trong đơn thừa kế, một lớp chỉ có thể có một lớp cơ sở. Trong đa thừa kế cho phép một lớp là dẫn xuất của nhiều lớp Lớp dẫn xuất thường bổ sung các thành phần dữ liệu và các hàm thành phần trong định nghĩa, ta nói lớp dẫn xuất cụ thể hơn so với lớp cơ sở và vì vậy thường mô tả một lớp các đối tượng có phạp vi hẹp hơn lớp cơ sở. Lớp dẫn xuất không có quyền truy nhập đến các thành phần private của lớp cơ sở. Tuy nhiên lớp cơ sở có quyền truy xuất đến các thành phần công cộng và được bảo vệ(proteced). Hàm thiết lập của lớp dẫn xuất thường tự động gọi các hàm thiết lập của các lớp cơ sở để khởi tạo giá trị cho các thành phần trong lớp cơ sở. Hàm huỷ bỏ được gọi theo thứ tự ngược lại. Thuộc tính truy nhập protected là mức trung gian giữa thuộc tính public và private. Chỉ có các hàm thành phần và hàm bạn của lớp cơ sở và lớp dẫn xuất có quyền truy xuất đến các thành phần protected của lớp cơ sở. Có thể định nghĩa lại các thành phần của lớp cơ sở trong lớp dẫn xuất khi thành đó không còn phù hợp trong lớp dẫn xuất. Có thể gán nội dung đối tượng lớp dẫn xuất cho một đối tượng lớp cơ sở. Một con trỏ lớp dẫn xuất có thể chuyển đổi thành con trỏ lớp cơ sở. Hàm ảo được khai báo với từ khoá virtual trong lớp cơ sở. Các lớp dẫn xuất có thể đưa ra các cài đặt lại cho các hàm ảo của lớp cơ sở nếu muốn, trái lại chúng có thể sử dụng định nghĩa đã nêu trong lớp cơ sở. Nếu hàm ảo được gọi bằng cách tham chiếu qua tên một đối tượng thì tham chiếu đó được xác định dựa trên lớp của đối tượng tương ứng. Một lớp có hàm ảo không có định nghĩa(hàm ảo thuần tuý) được gọi là lớp trừu tượng. Các lớp trừu tượng không thể dùng để khai báo các đối tượng nhưng có thể khai báo con trỏ có kiểu lớp trừu tượng. B. MỘT SỐ LƯU Ý (Các lỗi thường gặp, một số thói quen lập trình tốt...) Các lỗi thường gặp Cho con trỏ lớp dẫn xuất chỉ đến đối tượng lớp cơ sở mà không đảm bảo chắc chắn rằng phiên bản mới của hàm trong lớp dẫn xuất cũng trả về cùng gái trị như phiên bản cũ của hàm. Khai báo đối tượng của lớp trừu tượng LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++ Trang 50 Khai báo hàm thiết lập là hàm ảo. Một số thói quen lập trình tốt Khi thừa kế các khả năng không cần thiết trong lớp dẫn xuất, tốt nhất nên định nghĩa lại chúng. C/ BÀI TẬP MẪU Ví d 1: Giả sử có các lớp như trong khai báo. Chỉ ra các lỗi sai cho các lệnh của chương trình viết dưới đây. class A { public: void func(); }; class B: private class A { }; A a; B b; a.func(); A* pA =&b; B* pB=&a; Lời giải Lời gọi b.func() có lỗi bởi vì lớp B kế thừa lớp A theo chế độ private. Do vậy, tất cả các thành phần của A sẽ là private trong B, hơn nữa không thể truy nhập vào một thành phần private. Một đối tượng của lớp dẫn xuất cũng có thể coi là đối tượng của lớp cơ sở. Do vậy, khia báo A* pA=&b là hoàn toàn đúng. Nhưng điều ngược lại là không đúng, nên khai báo B* pB=&a sẽ gây lỗi khi biên dịch. Ví dụ 2: Quản lý học viên CT4_2.CPP #include #include class person_data { public: void getinfo(); void display(); person_data(); virtual ~person_data(); private: char name[25]; int roll_no; char sex; }; person_data::person_data() { } person_data::~person_data() { } void person_data::getinfo() { cout << "Ten: "; 29. LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++ Trang 51 cin>> name; cout<<"So: "; cin>>roll_no; cout<<"Gioi tinh(F/M) : "; cin>> sex; } void person_data:: display() { cout<<name<<"\t"; cout<<roll_no<<"\t"; cout<<sex<<"\t"; } //----------------------------------- class academics { public: void getinfo(); void display(); academics(); virtual ~academics(); private: char course_name[25]; int semester; char grade[3]; }; academics::academics() { } academics::~academics() { } void academics::getinfo() { cout<<"Ten khoa (BA/MBA/MCA etc)? "; cin>>course_name; cout<< "Hoc ky (1/2/3/...)? "; cin>>semester; cout<<"muc do (A,B,B+,B-..) ? "; cin>>grade; } void academics::display() { cout<<course_name<<"\t"; cout<<semester<<"\t"; cout<<grade<<"\t"; } //------------------------------- class stud_scholarship : public person_data, public academics { public: void getinfo(); void display(); stud_scholarship(); virtual ~stud_scholarship(); LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++ Trang 52 private: float amount; }; stud_scholarship::stud_scholarship() { } stud_scholarship::~stud_scholarship() { } void stud_scholarship::getinfo() { person_data::getinfo(); academics::getinfo(); cout<<"Su ho tro "; cin>>amount; } void stud_scholarship::display() { person_data::display(); academics::display(); cout<<amount<<endl; } //---------------------------------- int main() { stud_scholarship obj; cout<<"Nhap cac thong tin sau: "<<endl; obj.getinfo(); cout<<endl; cout<<"Ten So Gioi tinh Khoa Hoc ky Muc do"; cout<<" Amount"<<endl; obj.display(); return 0; } 30. D/ BÀI TẬP TỰ GIẢI Bài 1: Xây dựng lớp Stack với các thao tác cần thiết. Từ đó hãy dẫn xuất từ lớp Stack để đổi một số nguyên dương sang hệ đếm bất kỳ. Bài 2: Hãy xây dựng các lớp cần thiết trong phân cấp hình 5.2 Bài 3: Hãy xây dựng các lớp cần thiết trong phân cấp hình 5.3 để tính diện tích (hoặc diện tích xung quanh) và thể tích. Bài 4: Viết một phân cấp kế thừa cho các lớp Quadrilateral (hình tứ giác), Trapezoid (hình thang), Parallelogram (hình bình hành), Rectangle (hình chữ nhật), và Square (hình vuông). Trong đó Quadrilateral là lớp cơ sở của phân cấp.
File đính kèm:
- Lập trình hướng đối tượng với C++.pdf