Bài tập phương pháp lập trình hướng đối tượng

Co2005_Laptrinhhuongdoituong_The C++ Programming Language (Special 3rd Edition), Bjarne Stroustrup, 2000.Pdf

Java Object- Basic - Programming.Pdf

Lthdt_Pham Van At.Pdf

Lập Trình Hướng Đối Tượng Với Java Đoàn Văn Ban.Pdf

Paul Deitel, Harvey Deitel - C++ How To Program-Deitel (2017).Pdf

Sedgewick, Robert - Algorithms In C, Parts 1-4_ Fundamentals, Data Structures, Sorting, Searching-Addison Wesley (1998).Pdf

Tài liệu Bài tập lập trình hướng đối tượng C++ BỘ CÔNG THƯƠNG TRƯỜNG CAO ĐẲNG CÔNG NGHIỆP PHÚC YÊN BÀI TẬP LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG C++ CƠ BẢN THỰC HIỆN: TRẦN XUÂN THỨC CN: Trần Xuân Thức - 1- [email protected] Bài tập lập trình hướng đối tượng C++ I. DẠNG BÀI TẬP MÔ TẢ BẰNG LỜI. Toàn bộ các lớp, các mối quan hệ giữa các lớp được đề bài mô tả bằng lời một cách chi tiết. Dạng này dễ dàng xác định được các lớp của bài và mối quan hệ giữa chúng, các thuộc tính và phương thức trong mỗi lớp. Do vậy ta dễ dàng vẽ một sơ đồ cho mỗi bài (nếu cần). Sau đây là một số bài tập ví dụ: Bài 1.1: Xây dựng lớp Person gồm các thông tin: Họ và tên, Ngày sinh, Quê quán. Sau đó, xây dựng lớp dẫn xuất “Kỹ sư” ngoài các thông tin của lớp Person, lớp kỹ sư còn có các thông tin về: Ngành học, Năm tốt nghiệp (int) và các phương thức: Phương thức nhập: nhập các thông tin của kỹ sư. Phương thức xuất: xuất các thông tin lên màn hình. Xây dựng chương trình chính nhập vào một danh sách các kỹ sư. In danh sách của các kỹ sư lên màn hình và thông tin của các kỹ sư tốt nghiệp gần đây nhất (năm tốt nghiệp lớn nhất).

include

include

include

include class Person { public: char HT[30]; char NS[30]; char Q[30]; }; class Kysu:public Person { public: char NH[30]; int NTN; void nhap(); void xuat(); }; void Kysu::nhap() { cout<<"Ho ten: ";gets(HT);fflush(stdin); cout<<"Ngay sinh: ";gets(NS);fflush(stdin); cout<<"Que quan: ";gets(Q);fflush(stdin); cout<<"Nganh hoc: ";gets(NH);fflush(stdin); cout>NTN; } void Kysu::xuat() CN: Trần Xuân Thức - 2- [email protected] Bài tập lập trình hướng đối tượng C++ { cout<<"Ho ten: "<n; for(i=0;iMax) Max=a[i].NTN; cout<<"Ky su co nam tot nghiep gan day nhat la: \n"; for(i=0;i

include

include

include

include class Mayin { public: CN: Trần Xuân Thức - 3- [email protected] Bài tập lập trình hướng đối tượng C++ float TL; char NamSX[30]; char HangSX[30]; }; class Mkim:public Mayin { int Skim; int Tdo; public: void nhap(); void xuat(); }; class Mlaser:public Mayin { int DPG; int TD; public: void nhap(); void xuat(); }; void Mkim::nhap() { cout>TL; cout<<"Nam sx: ";gets(NamSX);fflush(stdin); cout<<"Hang sx: ";gets(HangSX);fflush(stdin); cout>Skim; cout>Tdo; } void Mkim::xuat() { cout<<"Trong luong may: "<TL; cout<<"Nam sx: ";gets(NamSX);fflush(stdin); cout<<"Hang sx: ";gets(HangSX);fflush(stdin); cout>DPG; cout>TD; } void Mlaser::xuat() { cout<<"Trong luong may: "<n; cout<<"May in kim:\n"; for(i=0;im; cout<<"May in laser:\n"; for(i=0;i

include

include

include

include class Person { public: char HT[50],NS[12],QQ[100]; void nhap(); CN: Trần Xuân Thức - 5- [email protected] Bài tập lập trình hướng đối tượng C++ void xuat(); Person() { strcpy(HT,"");strcpy(NS,"");strcpy(QQ,""); } }; class Diem { public: int Dtoan; int Dly; int Dhoa; void nhap(); void xuat(); Diem() { Dtoan=Dly=Dhoa=0; } }; class Hocsinh:public Person,public Diem { char Lop[30]; int TDiem; public: void nhap(); void xuat(); Hocsinh() { strcpy(Lop,"");TDiem=0; } }; void Person::nhap() { cout<<"Ho ten: ";gets(HT);fflush(stdin); cout<<"Ngay sinh: ";gets(NS);fflush(stdin); cout<<"Que quan: ";gets(QQ);fflush(stdin); } void Person::xuat() { cout<<"Ho ten: "<Dtoan; cout>Dly; CN: Trần Xuân Thức - 6- [email protected] Bài tập lập trình hướng đối tượng C++ cout>Dhoa; } void Diem::xuat() { cout<<"Diem toan: "<n; for(int i=0;i

include

include

include

include class NhaSX { char TenNSX[30]; char DC[30]; friend class May; friend class Maytinh; friend void In(Maytinh *a,int n); friend void Xoa(Maytinh *a,int *n); }; class May { public: char NH[30]; NhaSX NSX; float GT; void nhap(); void xuat(); }; class Maytinh:public May { float TD; int DLR; int DLHDD; public: void nhap(); void xuat(); CN: Trần Xuân Thức - 8- [email protected] Bài tập lập trình hướng đối tượng C++ friend void In(Maytinh *a,int n); friend void Sap(Maytinh *a,int n); friend void Xoa(Maytinh *a,int *n); }; void May::nhap() { cout<<"Nhan hieu: ";gets(NH);fflush(stdin); cout<<"Ten NSX: ";gets(NSX.TenNSX);fflush(stdin); cout<<"Dia chi: ";gets(NSX.DC);fflush(stdin); cout>GT; } void May::xuat() { cout<<"Nhan hieu: "<TD; cout>DLR; cout>DLHDD; } void Maytinh::xuat() { May::xuat(); cout<<"Toc do: "<n; for(i=0;i-May tinh cua hang IBM-\n"; In(a,n); cout<<"-Sap xep may tinh tang dan theo gia-\n"; Sap(a,n); CN: Trần Xuân Thức - 10- [email protected] Bài tập lập trình hướng đối tượng C++ CN: Trần Xuân Thức - 11- [email protected] for(i=0;i-DS may tinh con lai sau khi xoa-\n"; Xoa(a,&n); for(i=0;i

include

include

include

include class NhaSX { char TenNSX[30]; char DC[30]; friend class May; friend class Maytinh; friend void In(Maytinh *a,int n); friend void Xoa(Maytinh *a,int *n); }; class May { - Tốc độ - Dung lượng RAM - Dung lượng HDD void input(); void output(); Máy tính Nhà sản xuất private: - Tên NSX - Địa chỉ public: void input(); void output(); Máy - Nhãn hiệu - Nhà sản suất - Giá thành void input(); void output(); Bài tập lập trình hướng đối tượng C++ public: char NH[30]; NhaSX NSX; float GT; void nhap(); void xuat(); }; class Maytinh:public May { int TD; float DLR; float DLHDD; public: void nhap(); void xuat(); }; void May::nhap() { cout<<"Nhan hieu: ";gets(NH);fflush(stdin); cout<<"Ten NSX: ";gets(NSX.TenNSX);fflush(stdin); cout<<"Dia chi: ";gets(NSX.DC);fflush(stdin); cout>GT; } void May::xuat() { cout<<"Nhan hieu: "<TD; cout>DLR; cout>DLHDD; CN: Trần Xuân Thức - 12- [email protected] Bài tập lập trình hướng đối tượng C++ } void Maytinh::xuat() { May::xuat(); cout<<"Toc do: "<n; for(i=0;i-May tinh cua hang IBM-\n"; In(a,n); cout<<"-Sap xep-\n"; Sap(a,n); for(i=0;i-May tinh con lai sau khi xoa-\n"; Xoa(a,&n); for(i=0;i

include

include

include

include

include class Ve { public: int Giagoc; char Ngay[30]; void nhap(); void xuat(); }; class VeNL:public Ve { int Giam; float Giave; public: void nhap(); void xuat(); }; class VeTE:public Ve { int Giam; float Giave; public: void nhap(); void xuat(); }; void Ve::nhap() { cout>Giagoc; cout<<"Ngay: ";gets(Ngay);fflush(stdin); } void Ve::xuat() { cout<<"Gia goc: "<Giam; Giave=Giagoc-(Giagoc*Giam)/100; CN: Trần Xuân Thức - 15- [email protected] Bài tập lập trình hướng đối tượng C++ } void VeNL::xuat() { Ve::xuat(); cout<<"Giam: "<Giam; Giave=Giagoc-(Giagoc*Giam)/100; } void VeTE::xuat() { Ve::xuat(); cout<<"Giam: "<

include

include

include

include class Power { public: void Bat_Nguon(); void Tat_Nguon(); }; class OS { char Ten[30]; public: void Khoi_Dong(); void Tat_HDH(); friend class Computor; }; class CPU { Power Nguon; OS HDH; friend class Computor; }; class Monitor { int Do_Sang; public: void Datdosang(int ds); }; class Computor { Monitor Man_Hinh; CN: Trần Xuân Thức - 17- [email protected] Bài tập lập trình hướng đối tượng C++ CPU Cpu; public: void Cai_Dat(char *Ten); void Bat_CPU(); void Datdosang(int ds); void Tat_CPU(); }; void Power::Bat_Nguon() { cout<<"Nguon da bat"; } void Power::Tat_Nguon() { cout<<"Nguon da tat"; } void OS::Khoi_Dong() { cout<<"He dieu hanh da khoi dong. "<

include

include

include

include class Person { public: char HT[30]; int Tuoi; void nhap(); void xuat(); }; class Hospital { char TenBV[30],DC[30]; Person GD; friend class BN; friend void IN(BN *a,int n); }; class BN:public Person { char TS[30],CD[30]; Hospital BV; public: void nhap(); Person Họ tên Tuổi Hospital Person Tên BV Họ tên Tuổi Địa chỉ Nhap( ) Nhap( ) Xuat( ) Xuat( ) Bài tập lập trình hướng đối tượng C++ void xuat(); friend void IN(BN *a,int n); }; void Person::nhap() { cout<<"Ho ten: ";gets(HT);fflush(stdin); cout>Tuoi; } void Person::xuat() { cout<<"Ho ten: "<n; for(i=0;i Day sap xep\n"; for(i=0;i-BN duoc dieu tri co BS Hoang Ha-\n"; IN(a,n); getch(); } III. DẠNG PHIẾU. Với việc cài đặt các chức năng Nhập, Xuất cho một phiếu bất kỳ, ta dễ dàng chuyển chúng thành sơ đồ lớp. Với dạng này cần chú ý tới các thuộc tính suy diễn của phiếu. Thông thường đây là các thuộc tính mang tính thống kê và ta cần tính giá trị cho các thuộc tính này bằng cách thống kê các giá trị của các thuộc tính khác (ví dụ tính tổng số lượng tài sản bằng cách duyệt qua các tài sản cộng và dồn số lượng). Điều này rất dễ bị mọi người bỏ qua do nó thường không được chú ý và quan tâm đúng mức. Bài 3.1. Viết chương trình quản lý điểm của sinh viên với mỗi sinh viên có các thông tin về: Mã sinh viên, Tên sinh viên, Lớp học và Môn học, biết rằng một sinh viên chỉ thuộc 1 Lớp học và có nhiều môn học. Thông tin về Lớp học bao gồm: Tên lớp, khoá. Thông tin về môn học bao gồm: Tên môn, số trình, điểm. Yêu cầu chương trình có các chức năng sau: - Nhập thông tin cho n sinh viên sao cho mỗi sinh viên có đủ thông tin. - In ra danh sách các sinh viên vừa nhập gồm các thông tin: mã sinh viên, tên sinh viên, Tên lớp, Khoá. - In phiếu báo điểm cho từng sinh viên theo mẫu: Phiếu Báo điểm Mã sinh viên: SV001. Tên sinh viên: Nguyễn Hải Hà Lớp: Tin 2 Khoá: 52 Bảng điểm: Tên môn Số trình Điểm Cơ sở dữ liệu 4 8 Lập trình HĐT 3 7 Hệ điều hành 5 9 Điểm trung bình: 8.17 Trong đó điểm trung bình = (Số trình * Điểm)/  (Số trình)

include

include CN: Trần Xuân Thức - 21- [email protected] Bài tập lập trình hướng đối tượng C++

include

include

include class SV { char MaSV[10],TenSV[30]; public: void nhap(); void xuat(); }; class Lop { char TenL[30]; int Khoa; public: void nhap(); void xuat(); }; class Mon { char TenMH[30]; int ST; int Diem; public: void nhap(); void xuat(); friend class Phieu; }; class Phieu { SV a; Lop b; int n; Mon c[100]; public: void nhap(); void xuat(); }; void SV::nhap() { cout<<"Ma sinh vien: ";gets(MaSV);fflush(stdin); cout<<"Ten sinh vien: ";gets(TenSV);fflush(stdin); } void SV::xuat() { cout<<"Ma sinh vien: "<Khoa; } void Lop::xuat() { cout<<"Lop: "<ST; cout>Diem; } void Mon::xuat() { cout<n; for(int i=0;in; for(int i=0;i

include

include

include

include

include class BN { char TenBN[30]; char GT[20]; int Tuoi; char DC[30],TSB[30]; public: void nhap(); void xuat(); }; class BS { char TenBS[30]; char NoiCT[30]; public: CN: Trần Xuân Thức - 24- [email protected] Bài tập lập trình hướng đối tượng C++ void nhap(); void xuat(); }; class TC { char MaTC[30]; char TenTC[30]; public: void nhap(); void xuat(); }; class Phieu { char MaP[30],Ngay[30]; BN a; BS b; int n; TC c[100]; char KL[50]; public: void nhap(); void xuat(); }; void BN::nhap() { cout<<"Ten BN: ";gets(TenBN);fflush(stdin); cout<<"Gioi tinh: ";gets(GT);fflush(stdin); cout>Tuoi; cout<<"Dia chi: ";gets(DC);fflush(stdin); cout<<"Tien su benh: ";gets(TSB);fflush(stdin); } void BN::xuat() { cout<<"Ten benh nhan: "<n; for(int i=0;i

include

include

include

include

include class Nhanvien { char TenNV[30]; char CV[30]; public: void nhap(); void xuat(); }; class Phong { char TenP[30]; char MaP[30]; char TP[30]; public: void nhap(); void xuat(); }; class Taisan { char TenTS[30]; int SL; char TT[30]; public: void nhap(); void xuat(); friend class Phieu; }; class Phieu { char MP[30], Ngay[30]; Nhanvien a; Phong b; CN: Trần Xuân Thức - 27- [email protected] Bài tập lập trình hướng đối tượng C++ int n; Taisan c[100]; public: void nhap(); void xuat(); }; void Nhanvien::nhap() { cout<<"Ten NV: ";gets(TenNV);fflush(stdin); cout<<"Chuc vu: ";gets(CV);fflush(stdin); } void Nhanvien::xuat() { cout<<"Nhan vien kiem ke: "<SL; cout<<"Tinh trang: ";gets(TT);fflush(stdin); } void Taisan::xuat() { cout<n; for(int i=0;i

include

include

include

include class KH { CN: Trần Xuân Thức - 29- [email protected] Bài tập lập trình hướng đối tượng C++ char MaKH[10],TenKH[30],DC[30]; int DT; public: void nhap(); void xuat(); }; class Sach { char MaS[10],TenS[30]; float Gia; int SL; public: void nhap(); void xuat(); friend class Phieu; }; class Phieu { char MaP[10],Ngay[30]; KH a; int n; Sach b[100]; public: void nhap(); void xuat(); }; void KH::nhap() { cout<<"Ma khach hang: ";gets(MaKH);fflush(stdin); cout<<"Ten khach hang: ";gets(TenKH);fflush(stdin); cout<<"Dia chi: ";gets(DC);fflush(stdin); cout>DT; } void KH::xuat() { cout<<"Ma khach hang: "<Gia; cout>SL; } CN: Trần Xuân Thức - 30- [email protected] Bài tập lập trình hướng đối tượng C++ void Sach::xuat() { cout<n; for(int i=0;i

include

include

include

include

include class KH { char MaKH[10],TenKH[30],DC[30]; int CMND; char NC[30]; public: void nhap(); void xuat(); }; class Phong { char MaP[10],LP[20],Hang[20]; int SN; public: void nhap(); void xuat(); friend class Phieu; }; class Phieu { char MP[10],NDat[20],NDen[20]; int DC; KH a; int n,i; Phong b[100]; public: void nhap(); void xuat(); }; void KH::nhap() { cout<<"Ma khach hang: ";gets(MaKH);fflush(stdin); cout<<"Ten khach hang: ";gets(TenKH);fflush(stdin); CN: Trần Xuân Thức - 32- [email protected] Bài tập lập trình hướng đối tượng C++ cout<<"Dia chi: ";gets(DC);fflush(stdin); cout>CMND; cout<<"Cap tai: ";gets(NC);fflush(stdin); } void KH::xuat() { cout<<"Ma khach hang: "<SN; } void Phong::xuat() { cout<DC; a.nhap(); cout>n; for(int i=0;i), giảm một đơn vị (--), phép đổi dấu - Toán tử hai ngôi: Là nhũng toán tử thực hiện trên 2 toán hạng. Thuộc loại này bao gồm các toán tử cộng (+), trừ (-), nhân (*), chia (/). Trong lập trình, các toán tử cộng, trừ, nhân, chia, trên các toán hạng thông thường đã được định nghĩa sẵn, ta chỉ việc sử dụng. Tuy nhiên, một số toán tử trên các toán hạng đặc biệt lại chưa được định nghĩa. Ví dụ: phép cộng , trù, nhân, chia hai phân số, phép cộng, trừ, nhân, chia hai số phức .v.v.. Chương này nhằm giúp ta cách thức cài đặt các phép toán chưa được định nghĩa trong lập trình như vậy. Sau khi cài đặt, ta có thể sử dụng chúng như các toán tử thông thường. b. Hàm toán tử trong lập trình cấu trúc. Ta trở lại với phương pháp lập trình cấu trúc. Khi đó, một hàm toán tử có đặc điểm sau: - Hàm toán tử được cài đặt tương tự hàm thông thường, chỉ khác ở tên hàm và cách sử dụng. - Tên hàm: được viết theo dạng: operator - Cú pháp của hàm: operator (các đối số) { CN: Trần Xuân Thức - 34- [email protected] Bài tập lập trình hướng đối tượng C Thân hàm toán tử; } Ví dụ: Hàm toán tử cộng hai số thực bất kỳ được viết như sau: float operator + (float x, float y) { return x + y; } - Cách sử dụng hàm toán tử: Có hai cách gọi một hàm toán tử. Cách 1: gọi như hàm thông thường. VD: để cộng hai số thực a, b ta có thể viết: cout<< “Tong cua hai so a va b la” << operator+(a,b); Cách 2: gọi như một toán tử: Ta có thể sử dụng hàm toán tử như một toán tử, tức là ta có thể viết: cout<< “Tong cua hai so S1 va S2 la” << S1 + S2; Phép cộng trên sẽ gọi tới hàm toán tử cộng đã định nghĩa. VD: Một số phức có dạng: + i * . Cho hai số phức X = a + i*b và Y = c + i * d. Khi đó X + Y sẽ cho số phức có dạng: X+Y = (a+c) + i * (b + d). Hãy định nghĩa hàm toán tử để thực hiện cộng hai số phức bất kỳ. typedef struct SP { float Phanthuc; float Phanao; }; //Dinh nghia ham toan tu cong hai so phuc SP operator+(SP x, SP y) { SP tg; tg.Phanthuc = x.Phanthuc + y.Phanthuc; tg.Phanao = x.Phanao + y.Phanao; return tg; } void main() { //Khai bao hai so phuc x va y va so phuc tong T SP x,y, T; x.Phanthuc = 2; x.Phanao = 3; y.Phanthuc= 3; y.Phanao = 5; //Cong hai so phuc va in ket qua len man hinh T = operator+(x, y); //Co the viet T = x + y cout<<"Ket qua "< Phanthuc; tg.Phanao = -this -> Phanao; - Khi sử dụng phương thức toán tử một ngôi ta cũng có 2 cách như với hàm toán tử. Như vậy, hai cách viết sau là tương đương: SoPhuc y = x.operator-(); SoPhuc y = -x; b. Cài đặt phương thức toán tử hai ngôi Như đã biết, trong phương thức toán tử, con trỏ this luôn là một đối số mặc định. Như vậy, với phương thức toán tử hai ngôi, thay vì có hai đối vào, ta chỉ cần một đối, đối còn lại là con trỏ this. Tương tự như phương thức toán tử một ngôi, ta nhận thấy: - Phương thức toán tử hai ngôi có 1 đối vào. Đối vào còn lại chính là con trỏ this. - Con trỏ this luôn là đối mặc định của các phương thức toán tử. Như vậy, hai cách viết sau là tương đương tg.Phanthuc = Phanthuc + y.Phanthuc; tg.Phanao = Phanao + y.Phanao; tg.Phanthuc = this -> Phanthuc + y.Phanthuc; tg.Phanao = this -> Phanao + y.Phanao; - Khi sử dụng phương thức toán tử hai ngôi ta cũng có 2 cách như với hàm toán tử. Như vậy, hai cách viết sau là tương đương: SoPhuc T = x.operator+(y); SoPhuc T = x + y 3. Cài đặt một số phương thức toán tử: Bài 4.2. Hãy xây dựng lớp phân số với các thuộc tính Tử số và Mẫu số và các phương thức: Toán tử nhập (>>) và xuất (<<) đưa phân số ra màn hình (dưới dạng Tử số/ Mẫu số). Phương thức khởi tạo, khởi gán Tử số và Mẫu số. CN: Trần Xuân Thức - 36- [email protected] Bài tập lập trình hướng đối tượng C++ Viết chương trình chính nhập vào hai phân số, đưa ra màn hình phân số là tổng và hiệu của hai phân số vừa nhập.

include

include

include class PS { float TS,MS; public: friend istream & operator>>(istream & x,PS & y); friend ostream & operator<<(ostream & x,PS & y); PS operator+(PS y); PS operator-(PS y); PS() { TS=0; MS=1; } PS(float t, float m) { TS=t; MS=m; } }; istream & operator>>(istream & x,PS & y) { cout>y.TS; cout>y.MS; return x; } ostream & operator<<(ostream & x,PS & y) { x<x; cout<y; cout<

include

include

include class PS { int TS,MS; public: friend istream & operator>>(istream & x,PS & y); friend ostream & operator<<(ostream & x,PS & y); PS operator*(PS y); CN: Trần Xuân Thức - 38- [email protected] Bài tập lập trình hướng đối tượng C++ }; istream & operator>>(istream & x,PS & y) { cout>y.TS; cout>y.MS; return x; } ostream & operator<<(ostream & x,PS & y) { x<x; cout<y; cout<

include

include

include class SP { float T,A; public: friend istream & operator>>(istream & x,SP & y); friend ostream & operator<<(ostream & x,SP & y); SP operator+(SP y); SP operator-(SP y); SP() { T=A=0; } SP(float x1,float x2) { T=x1;A=x2; } }; istream & operator>>(istream & x,SP & y) { cout>y.T; cout>y.A; return x; } ostream & operator<<(ostream & x,SP & y) { x<x; cout<y; cout<>) và xuất (<<): nhập các giá trị m, n và ma trận a. Xuất ma trận: xuất các giá trị của ma trận a lên màn hình. Phương thức toán tử “Đổi dấu ma trận” (-): đổi dấu tất cả các phần tử của ma trận. Xây dựng chương trình chính trong đó khai báo một đối tượng thuộc lớp ma trận. Nhập các giá trị cho ma trận, đổi dấu ma trận và in ma trận đã đổi dấu ra màn hình.

include

include

include

include class MT { int n,m; float a[100][100]; public: friend istream & operator>>(istream & x,MT & y); friend ostream & operator<<(ostream & x,MT & y); MT operator-(); }; istream & operator>>(istream & x,MT & y) { cout>y.n; CN: Trần Xuân Thức - 41- [email protected] Bài tập lập trình hướng đối tượng C++ cout>y.m; for(int i=0;i>y.a[i][j]; } return x; } ostream & operator<<(ostream & x,MT & y) { for(int i=0;iy; z=-y; cout<<"Doi dau: \n"<>) và xuất (<<) ma trận. Xây dựng chương trình chính minh hoạ cách sử dụng các phương thức toán tử trên.

include CN: Trần Xuân Thức - 42- [email protected] Bài tập lập trình hướng đối tượng C++

include

include

include class MT { int n,m; float a[100][100]; public: friend istream & operator>>(istream & x,MT & y); friend ostream & operator<<(ostream & x,MT & y); MT operator-(); }; istream & operator>>(istream & x,MT & y) { cout>y.n; cout>y.m; for(int i=0;i>y.a[i][j]; } return x; } ostream & operator<<(ostream & x,MT & y) { for(int i=0;iy; z=-y; cout<<"Ma tran chuyen vi: \n"<

include

include

include class TT { float a,b,c; public: friend istream & operator>>(istream & x,TT & y); friend ostream & operator<<(ostream & x,TT & y); TT operator+(TT y); CN: Trần Xuân Thức - 44- [email protected] Bài tập lập trình hướng đối tượng C++ TT operator-(); }; istream & operator>>(istream & x,TT & y) { cout>y.a; cout>y.b; cout>y.c; return x; } ostream & operator<<(ostream & x,TT & y) { x<x; CN: Trần Xuân Thức - 45- [email protected] Bài tập lập trình hướng đối tượng C++ cout<y; cout<x; cout<<"Mang tang dan:\n"; z.xuat(); z=--x; cout<<"\nMang giam dan:\n"; z.xuat(); getch(); } Bài 4.8. Xây dựng các lớp thời gian (TIME) để lưu trữ thời gian gồm: Giờ, phút, giây. Thực hiện cài đặt toán tử nhập (>>), xuất (<<) và các phép toán tử +, , < VD: TIME A(1,59,59), B, C; Cin>>B //nhập: 1, 59, 6 C=A+B; Cout<

include

include

include CN: Trần Xuân Thức - 48- [email protected] Bài tập lập trình hướng đối tượng C++ class Time { int g,p,gi; public: friend istream & operator>>(istream & x,Time & y); friend ostream & operator<<(ostream & x,Time & y); Time operator+(Time y); void operator++(); int operator<(Time y); Time(int g1=0,int p1=0,int gi1=0) { g=g1; p=p1; gi=gi1; } }; istream & operator>>(istream & x,Time & y) { cout>y.g; cout>y.p; cout>y.gi; return x; } ostream & operator<<(ostream & x,Time & y) { x<=60) { z.gi=z.gi%60; z.p=z.p+1; } if(z.p>=60) { z.p=z.p%60; z.g=z.g+1; } return z; } void Time::operator++() { gi=gi+1; if(gi==60) { gi=0; p=p+1; } CN: Trần Xuân Thức - 49- [email protected] Bài tập lập trình hướng đối tượng C++ if(p==60) { p=0; g=g+1; } } int Time::operator<(Time y) { if(gy.g) return 0; else if(py.p) return 0; else if(gi>B; C=A+B; cout<a; } }; class B: public A { int b; public: void nhap() { cout>b; } }; class C: public B { int c; public: void nhap() { cout>c; } }; Tại hàm main(), ta khai báo 3 đối tượng thuộc 3 lớp A, B, C và một con trỏ p thuộc lớp A. Khi đó, mặc dù p trỏ tới đối tượng của lớp B, C những khi viết p  nhap() thì phương thức nhap() của lớp A vẫn được gọi. void main() { A d1, *p; B d2; C d3; CN: Trần Xuân Thức - 51- [email protected] Bài tập lập trình hướng đối tượng C++ p = & d2; p->nhap();//van la phuong thuc nhap() cua lop A p = & d3; p->nhap();//van la phuong thuc nhap() cua lop A } 2. Phương thức ảo và ý nghĩa của phương thức ảo Trong nhiều trường hợp, ta mong muốn: Khi con trỏ đối tượng p thuộc lớp A đang chứa địa chỉ của một đối tượng thuộc lớp B hoặc C mà ta viết: P  nhap(); thì sẽ truy cập tới phương thức nhap() của lớp B hoặc C. Muốn được như vậy thì phương thức nhap() của 3 lớp A, B, C phải là phương thức ảo. Các phương thức viết theo kiểu thông thường đều là các phương thức tĩnh. Phương thức nhap() trong ví dụ trên là phương thức tĩnh. Cách chuyển phương thức tĩnh thành phương thức ảo: Cách 1: Thêm từ khoá virtual vào trước phương thức tĩnh của cả tất cả các lớp (cơ sở và dẫn xuất). VD: Đoạn trình sau chuyển phương thức tĩnh nhap() thành phương thức ảo: class A { int a; public: virtual void nhap() { cout>a; } }; class B: public A { int b; public: virtual void nhap() { cout>b; } }; class C: public B { int c; CN: Trần Xuân Thức - 52- [email protected] Bài tập lập trình hướng đối tượng C++ public: virtual void nhap() { cout>c; } }; Cách 2: Chỉ cần thêm từ khoá virtual vào trước phương thức tĩnh của lớp cơ sở. class A { int a; public: virtual void nhap() { cout>a; } }; class B: public A { int b; public: void nhap() { cout>b; } }; class C: public B { int c; public: void nhap() { cout>c; } }; Khi đó, trong chương trình chính, nếu p trỏ tới đối tượng của lớp nào thì phương thức nhap() của đối tượng thuộc lớp đó sẽ được gọi khi ta viết p  nhap(); void main() { A d1, *p; B d2; CN: Trần Xuân Thức - 53- [email protected] Bài tập lập trình hướng đối tượng C++ C d3; p = & d2; p->nhap();//phuong thuc nhap() cua lop B duoc goi p = & d3; p->nhap();//phuong thuc nhap() cua lop C duoc goi } 3. Phương thức ảo và sự kết nối động Trong ví dụ trên, cùng một lời gọi phương thức : p  nhap(); nhưng có thể truy cập tới phương thức ảo của lớp A hoặc B hoặc C. Lời gọi p  nhap(); tương ứng với 3 phương thức nhap() khác nhau. Khi ta sử dụng phương thức ảo, rõ ràng là: cùng một con trỏ thuộc lớp cơ sở, cùng một lời gọi phương thức nhưng lời gọi đó lại tương ứng với nhiều phương thức khác nhau. Ta gọi đó là sự tương ứng bội hay tính đa hình. Lời gọi p  nhap(); có thể kết nối tới phương thức nhap() của lớp A hoặc lớp B, hoặc lớp C. Điều đó có nghĩa là lời gọi đó không liên kết cứng tới một phương thức nhap() nào mà sự liên kết đó là động. Như vậy, khi sử dụng phương thức ảo thì ta có thể liên kết động từ một lời gọi phương thức tới nhiều phương thức cùng tên, cùng bộ đối số. Tính chất như vậy của phương thức ảo gọi là sự kết nối động. 4. Ví dụ về sử dụng phương thức ảo Xây dựng lớp Cây gồm các thuộc tính: Chiều cao, độ tuổi, chu vi tán và các phương thức: - Phương thức nhập: nhập các giá trị cho các thuộc tính của lớp Cây. - Phương thức xuất: xuất các giá trị của các thuộc tính thuộc lớp Cây lên màn hình. Xây dựng lớp Cây cảnh, ngoài các thuộc tính của lớp Cây còn có các thuộc tính: Giá thành, chủng loại và các phương thức: - Phương thức nhập: nhập các giá trị cho các thuộc tính của lớp Cây cảnh. - Phương thức xuất: xuất các giá trị của các thuộc tính thuộc lớp Cây cảnh lên màn hình. Viết chương trình chính khai báo 2 đối tượng thuộc 2 lớp trên và một con trỏ thuộc lớp Cây. Dùng con trỏ này để nhập, xuất các thuộc tính của hai đối tượng trên. class Cay { public: float Chieucao; float Dotuoi; float CVTan; public: virtual void nhap() CN: Trần Xuân Thức - 54- [email protected] Bài tập lập trình hướng đối tượng C++ { cout<<"Nhap thong tin cho Cay "<Chieucao; cout>Dotuoi; cout>CVTan; } virtual void xuat() { cout<<"Thong tin cua lop Cay "<Chieucao; cout>Dotuoi; cout>CVTan; cout>Giathanh; cout<<"Chung loai "; gets(Chungloai); } void xuat() { cout<<"Thong tin cua lop Cay Canh "<nhap();//Nhap cua lop Cay p=&b; p->nhap();//Nhap cua lop Caycanh p=&a; p->xuat();//Xuat cua lop Cay p=&b; p->xuat();//Xuat cua lop Caycanh getch(); } 5. Lớp cơ sở trừu tượng và các thành phần ảo Trong nhiều trường hợp, ta chỉ muốn dùng con trỏ của lớp cơ sở để truy cập tới các phương thức ảo của các lớp dẫn xuất. Ngoài ra, rất ít khi dùng con trỏ lớp cơ sở để truy cập tới phương thức ảo của chính lớp này. Tuy nhiên, để con trỏ của lớp cơ sở có thể truy cập các phương thức ảo của các lớp dẫn xuất thì lớp cơ sở cũng phải có phương thức ảo này. Từ đây xuất hiện một khả năng: Phương thức ảo của lớp cơ sở có thể chỉ được định nghĩa hình thức mà không được dùng. Khi đó thân của phương thức ảo này không cần có bất cứ dòng lệnh nào. Một phương thức ảo của lớp cơ sở mà trong thân của nó không thực thi một lệnh nào (trừ return) gọi là phương thức thuần ảo. Lớp cơ sở có phương thức thuần ảo gọi là lớp cơ sở trừu tượng. Khi thiết kế phần mềm hướng đối tượng, ta luôn xác định được các lớp có thể có trong phần mềm và cây thứ bậc thể hiện sự kế thừa của các lớp. Người ta thường tạo ra các lớp cơ sở trừu tượng, trong đó có các phương thức thuần ảo. Những phương thức như vậy không thực hiện một công việc nào mà chỉ dùng để tạo phương thức ảo cho các phương thức cùng tên trong các lớp dẫn xuất. Từ đó, chỉ cần khai báo một con trỏ thuộc lớp cơ sở trừu tượng này, ta có thể dùng con trỏ đó để truy cập tới các phương thức ảo của các lớp dẫn xuất. Từ đây, tạo ra sự linh hoạt trong truy cập các lớp dẫn xuất. Phương thức ảo chỉ được tạo ra sau khi đã hình thành đối tượng, do vậy, phương thức khởi tạo không thể là phương thức ảo nhưng phương thức huỷ bỏ có thể là phương thức ảo. Ngoài ra, phương thức toán tử cũng có thể là phương thức ảo. Ưu nhược điểm của phương thức ảo: - Chương trình sử dụng nhiều phương thức ảo sẽ linh hoạt hơn trong sự truy cập các phương thức cùng tên của các lớp dẫn xuất. - Việc thực thi chương trình sẽ chậm hơn. - Tốn nhiều bộ nhớ hơn do phải tạo ra một bảng chỉ mục của các phương thức ảo. CN: Trần Xuân Thức - 56- [email protected] Bài tập lập trình hướng đối tượng C++ Khi nào dùng phương thức ảo? Ta chỉ thiết kế các lớp có phương thức ảo khi: - Có sự kế thừa giữa các lớp. - Các lớp trong cây thứ bậc có các phương thức cùng tên, cùng đối số, lớp cơ sở ban đầu (lớp gốc) bắt buộc cũng phải có phương thức này. - Bản chất của cây thứ bậc đòi hỏi cần có phương thức ảo. Bài 5.1. Xây dựng lớp cơ sở Xe gồm thuộc tính năm sản xuất, trọng lượng và phương thức tính giá thành: Giá thành = (năm sản xuất * 0.2 + trọng lượng), phương thức khởi tạo khởi gán các giá trị cho các thuộc tính của lớp Xe, phương thức Xuất đưa các thông tin của xe và giá thành lên màn hình. Xây dựng lớp dẫn xuất Xe tải kế thừa tất cả các thuộc tính và phương thức trên của lớp Xe, ngoài ra còn có thêm thuộc tính Trọng tải và các phương thức: Phương thức khởi tạo: khởi gán các giá trị thuộc tính cho xe tải. Phương thức Tính giá thành: Giá thành = Trọng tải *200. Phương thức xuất, đưa các thông tin và giá thành của xe tải lên màn hình. Xây dựng chương trình chính sử dụng một con trỏ đối tượng thuộc lớp Xe. Sử dụng con trỏ này để nhập thông tin cho đối tượng thuộc lớp Xe và in các thông tin vừa nhập lên màn hình kèm theo giá thành của Xe. Vẫn sử dụng con trỏ này để nhập thông tin cho đối tượng thuộc lớp Xe tải và in các thông tin vừa nhập lên màn hình kèm theo giá thành của Xe tải.

include

include

include

include class Xe { public: int NamSX; float TL; Xe(int x1,float x2) { NamSX=x1; TL=x2; } Xe() { NamSX=TL=0; } virtual void nhap() { cout>NamSX; cout>TL; } virtual void gt() { float GT=0; GT=(NamSX*0.2+TL); CN: Trần Xuân Thức - 57- [email protected] Bài tập lập trình hướng đối tượng C++ cout<<"Gia thanh: "<TT; } void gt() { float G=0; G=TT*200; cout<<"Gia thanh: "<Nhap thong tin lop xe\n"; p=&a; p->nhap(); cout<<"Nhap thong tin lop xe tai\n"; p=&b; p->nhap(); cout<<"Xuat thong tin lop xe\n"; p=&a; p->xuat(); p->gt(); CN: Trần Xuân Thức - 58- [email protected] Bài tập lập trình hướng đối tượng C++ CN: Trần Xuân Thức - 59- [email protected] cout<<"Xuat thong tin lop xe tai\n"; p=&b; p->xuat(); p->gt(); getch(); }