Trong loạt bài viết này, chúng ta đã tìm hiểu về lập trình hướng đối tượng. Trong bài viết cuối cùng này, chúng ta sẽ làm một vài bài tập lập trình hướng đối tượng tổng hợp để củng cố kiến thức đã học.
Bài tập lập trình hướng đối tượng cơ bản
Bài tập xây dựng lớp Phân số
Đề bài:
Xây dựng lớp Phanso
gồm:
- Thuộc tính: tử số (
tuso
), mẫu số (mauso
). - Phương thức:
- Hàm Khởi Tạo Không Tham Số, Hàm Hủy
- Nhập, Xuất
- Cộng, Trừ, Nhân, Chia
Tính tổng, hiệu, tích, thương của 2 phân số obj1
và obj2
, sau đó in kết quả ra màn hình.
Code xây dựng class Phân số:
#include
using namespace std;
class Phanso {
private:
int tuso, mauso;
public:
Phanso() {
tuso = 0;
mauso = 1;
}
~Phanso() {
tuso = 0;
mauso = 1;
}
void nhap() {
cout << "Nhập Tử Số: ";
cin >> this->tuso;
cout << "Nhập Mẫu Số: ";
cin >> this->mauso;
}
void xuat() {
cout << this->tuso << "/" << this->mauso << endl;
}
Phanso cong(Phanso obj1, Phanso obj2) {
Phanso obj3;
obj3.tuso = obj1.tuso * obj2.mauso + obj1.mauso * obj2.tuso;
obj3.mauso = obj1.mauso * obj2.mauso;
return obj3;
}
Phanso tru(Phanso obj1, Phanso obj2) {
Phanso obj3;
obj3.tuso = obj1.tuso * obj2.mauso - obj1.mauso * obj2.tuso;
obj3.mauso = obj1.mauso * obj2.mauso;
return obj3;
}
Phanso nhan(Phanso obj1, Phanso obj2) {
Phanso obj3;
obj3.tuso = obj1.tuso * obj2.tuso;
obj3.mauso = obj1.mauso * obj2.mauso;
return obj3;
}
Phanso chia(Phanso obj1, Phanso obj2) {
Phanso obj3;
obj3.tuso = obj1.tuso * obj2.mauso;
obj3.mauso = obj1.mauso * obj2.tuso;
return obj3;
}
};
int main() {
Phanso obj1, obj2, obj3;
obj1.nhap();
obj2.nhap();
obj3 = obj3.cong(obj1, obj2);
obj3.xuat();
obj3 = obj3.tru(obj1, obj2);
obj3.xuat();
obj3 = obj3.nhan(obj1, obj2);
obj3.xuat();
obj3 = obj3.chia(obj1, obj2);
obj3.xuat();
return 0;
}
Input:
1 2 3 4
Output:
10/8 -2/8 3/8 4/6
Bài Tập quản lý Vận động viên
Đề bài:
Xây dựng lớp VanDongVien
gồm:
- Thuộc tính: họ tên (
hoten
- chuỗi ký tự), tuổi (tuoi
- số nguyên), môn thi đấu (monthidau
- chuỗi ký tự), cân nặng (cannang
- số thực), chiều cao (chieucao
- số thực). - Phương thức:
- Thiết lập không tham số.
- Thiết lập 5 tham số.
- Hủy bỏ.
- Nạp chồng toán tử nhập (>>).
- Nạp chồng toán tử xuất (<<).
- Nạp chồng toán tử so sánh (>): một vận động viên là lớn hơn nếu chiều cao lớn hơn, trong trường hợp chiều cao bằng nhau thì xét cân nặng lớn hơn.
Xây dựng chương trình chính:
- Khai báo
p
là đối tượng lớpVanDongVien
(sử dụng hàm thiết lập 5 tham số), hiển thị thông tin củap
ra màn hình. - Nhập vào một mảng gồm
n
vận động viên. - Hiển thị danh sách đã nhập ra màn hình.
- Sắp xếp mảng đã nhập theo thứ tự tăng dần, hiển thị danh sách đã sắp ra màn hình.
Lời Giải:
#include
using namespace std;
class VanDongVien {
protected:
string hoten, monthidau;
int tuoi;
float cannang, chieucao;
public:
VanDongVien() {
this->hoten = this->monthidau = "";
this->tuoi = 0;
this->cannang = this->chieucao = 0;
}
VanDongVien(string hoten, string monthidau, int tuoi, float cannang, float chieucao) {
this->hoten = hoten;
this->monthidau = monthidau;
this->tuoi = tuoi;
this->cannang = cannang;
this->chieucao = chieucao;
}
~VanDongVien() {
this->hoten = this->monthidau = "";
this->tuoi = 0;
this->cannang = this->chieucao = 0;
}
friend istream& operator>>(istream& is, VanDongVien& obj) {
cin.ignore();
cout << "Nhập Họ Tên: ";
fflush(stdin);
getline(is, obj.hoten);
cout << "Nhập Môn Thi Đấu: ";
fflush(stdin);
getline(is, obj.monthidau);
cout << "Nhập Tuổi: ";
is >> obj.tuoi;
cout << "Nhập Cân Nặng: ";
is >> obj.cannang;
cout << "Nhập Chiều Cao: ";
is >> obj.chieucao;
return is;
}
friend ostream& operator<<(ostream& os, VanDongVien obj) {
cout << "Họ Tên: " << obj.hoten << endl;
cout << "Môn Thi Đấu: " << obj.monthidau << endl;
cout << "Tuổi: " << obj.tuoi << endl;
cout << "Cân Nặng: " << obj.cannang << endl;
cout << "Chiều cao: " << obj.chieucao << endl;
return os;
}
bool operator>(const VanDongVien& obj) {
if (this->chieucao > obj.chieucao)
return true;
else if (this->chieucao < obj.chieucao)
return false;
else if (this->cannang > obj.cannang)
return true;
else
return false;
}
};
void swap(VanDongVien& a, VanDongVien& b) {
VanDongVien temp = a;
a = b;
b = temp;
}
void Bubblesort(VanDongVien arr[], int n) {
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}
int main() {
VanDongVien p("Nguyen Van A", "Bong Da", 20, 178, 70.5);
cout << p;
cout << "Nhập Số Lượng: ";
int n;
cin >> n;
VanDongVien* arr = new VanDongVien[n];
for (int i = 0; i < n; ++i)
cin >> arr[i];
cout << endl << endl;
for (int i = 0; i < n; ++i)
cout << arr[i] << endl;
cout << "Sort" << endl;
Bubblesort(arr, n);
for (int i = 0; i < n; ++i)
cout << arr[i] << endl;
return 0;
}
Input:
3 Nguyen Van B Cau Long 20 80 190 Nguyen Van C Bong Chuyen 21 78 188 Nguyen Van D Boi Loi 19 81 188
Output:
Ho Ten: Nguyen Van A
Mon Thi Dau: Bong Da
Tuoi: 20
Can Nang: 178
Chieu cao: 70.5
Ho Ten: Nguyen Van B
Mon Thi Dau: Cau Long
Tuoi: 20
Can Nang: 80
Chieu cao: 190
Ho Ten: Nguyen Van C
Mon Thi Dau: Bong Chuyen
Tuoi: 21
Can Nang: 78
Chieu cao: 188
Ho Ten: Nguyen Van D
Mon Thi Dau: Boi Loi
Tuoi: 19
Can Nang: 81
Chieu cao: 188
Sort
Ho Ten: Nguyen Van C
Mon Thi Dau: Bong Chuyen
Tuoi: 21
Can Nang: 78
Chieu cao: 188
Ho Ten: Nguyen Van D
Mon Thi Dau: Boi Loi
Tuoi: 19
Can Nang: 81
Chieu cao: 188
Ho Ten: Nguyen Van B
Mon Thi Dau: Cau Long
Tuoi: 20
Can Nang: 80
Chieu cao: 190
Bài Tập OOP nâng cao
Bài Tập quản lý bán vé máy bay
Đề bài:
Xây dựng lớp Vemaybay
gồm:
- Thuộc tính: tên chuyến (
tenchuyen
- chuỗi ký tự), ngày bay (ngaybay
- kiểuDate
), giá vé (giave
- số nguyên). - Phương thức:
- Cấu tử
- Hủy
- Nhập
- Xuất
getgiave()
: hàm trả về giá vé
Xây dựng lớp Nguoi
gồm:
- Thuộc tính: họ tên (
hoten
- chuỗi ký tự), giới tính (gioitinh
- chuỗi ký tự), tuổi (tuoi
- số nguyên). - Phương thức:
- Cấu tử
- Hủy
- Nhập
- Xuất
Xây dựng lớp Hanhkhach
(mỗi hành khách có thể mua nhiều vé) kế thừa lớp Nguoi
bổ sung thêm:
- Thuộc tính:
Vemaybay *ve
,int soluong
(con trỏ đến vé máy bay và số lượng). - Phương thức:
- Cấu tử
- Hủy
- Nhập
- Xuất
tongtien()
: trả về tổng số tiền phải trả của hành khách
Chương trình chính:
- Nhập vào 1 danh sách
n
hành khách (n nhập từ bàn phím). - Hiển thị danh sách hành khách và số tiền phải trả tương ứng của mỗi khách hàng.
- Sắp xếp danh sách hành khách theo chiều giảm dần của Tổng tiền.
Lời Giải:
#include
using namespace std;
class Date {
protected:
int day, month, year;
public:
Date() {
this->day = this->month = this->year = 0;
}
~Date() {
this->day = this->month = this->year = 0;
}
void input() {
cout << "Nhập Ngày: ";
cin >> this->day;
cout << "Nhập Tháng: ";
cin >> this->month;
cout << "Nhập Năm: ";
cin >> this->year;
}
void output() {
cout << this->day << "/" << this->month << "/" << this->year << endl;
}
};
class Vemaybay {
protected:
string tenchuyen;
Date ngaybay;
int giave;
public:
Vemaybay() {
this->tenchuyen = "";
this->giave = 0;
}
~Vemaybay() {
this->tenchuyen = "";
this->giave = 0;
}
void input() {
cin.ignore();
cout << "Nhập Tên Chuyến: ";
fflush(stdin);
getline(cin, this->tenchuyen);
cout << "Nhập Ngày Bay: " << endl;
ngaybay.input();
cout << "Nhập Giá Vé: ";
cin >> this->giave;
}
void output() {
cout << "Tên Chuyến: " << this->tenchuyen << endl;
cout << "Ngày Bay: " << endl;
this->ngaybay.output();
cout << "Giá Vé: " << this->giave << endl;
}
int getgiave() {
return this->giave;
}
};
class Nguoi {
protected:
string hoten, gioitinh;
int tuoi;
public:
Nguoi() {
this->hoten = this->gioitinh = "";
this->tuoi = 0;
}
~Nguoi() {
this->hoten = this->gioitinh = "";
this->tuoi = 0;
}
void input() {
cin.ignore();
cout << "Nhập Họ Tên: ";
fflush(stdin);
getline(cin, this->hoten);
cout << "Nhập Giới Tính: ";
fflush(stdin);
getline(cin, this->gioitinh);
cout << "Nhập Tuổi: ";
cin >> this->tuoi;
}
void output() {
cout << "Họ Tên: " << this->hoten << endl;
cout << "Giới Tính: " << this->gioitinh << endl;
cout << "Tuổi: " << this->tuoi << endl;
}
};
class Hanhkhach : public Nguoi {
protected:
int soluong;
Vemaybay ve[1000];
int tongtien;
public:
Hanhkhach() {
this->soluong = 0;
this->ve[this->soluong];
this->tongtien = 0;
}
~Hanhkhach() {
soluong = 0;
tongtien = 0;
}
void input() {
Nguoi::input();
cout << "Nhập Số Lượng Vé Hành Khách Đã Mua: ";
cin >> this->soluong;
for (int i = 0; i < this->soluong; ++i) {
ve[i].input();
tongtien += ve[i].getgiave();
}
}
void output() {
cout << "- Thông Tin Khách Hàng: " << endl;
Nguoi::output();
cout << "- Thông Tin Chuyến Bay: " << endl;
for (int i = 0; i < this->soluong; ++i) {
ve[i].output();
cout << endl;
}
cout << "===> Tổng Tiền = " << this->tongtien << endl;
}
bool operator<(const Hanhkhach& obj) {
if (this->tongtien < obj.tongtien)
return true;
else
return false;
}
};
void swap(Hanhkhach& a, Hanhkhach& b) {
Hanhkhach temp = a;
a = b;
b = temp;
}
void Bubblesort(Hanhkhach arr[], int n) {
for (int i = 0; i < n - 1; ++i)
for (int j = 0; j < n - i - 1; ++j)
if (arr[j] < arr[j + 1])
swap(arr[j], arr[j + 1]);
}
int main() {
cout << "Nhập Số Lượng Khách Hàng: ";
int n;
cin >> n;
Hanhkhach* arr = new Hanhkhach[n];
for (int i = 0; i < n; ++i)
arr[i].input();
cout << endl << endl << "Output" << endl << endl;
for (int i = 0; i < n; ++i) {
arr[i].output();
cout << endl << "-" << endl << endl;
}
cout << "After Sort: " << endl;
Bubblesort(arr, n);
for (int i = 0; i < n; ++i) {
arr[i].output();
cout << endl << "-" << endl << endl;
}
return 0;
}
Input:
3 Nguyen Van A Nam 20 2 Ha Noi - Hai Phong 10 2 2020 500000 Hai Phong - Ha Noi 15 2 2020 450000 Nguyen Van B Nam 21 1 Ha Noi - TP.Ho Chi Minh 20 2 2020 1500000 Nguyen Thi C Nu 19 3 Ha Noi - Da Nang 19 2 2020 1200000 Ha Noi - Hue 18 2 2020 1250000 Hue - Da Nang 22 2 2020 500000
Output:
- Thông Tin Khách Hàng:
Họ Tên: Nguyen Van A
Giới Tính: Nam
Tuổi: 20
- Thông Tin Chuyến Bay:
Tên Chuyến: Ha Noi - Hai Phong
Ngày Bay:
Ngày/Tháng/Năm: 10/2/2020
Giá Vé: 500000
Tên Chuyến: Hai Phong - Ha Noi
Ngày Bay:
Ngày/Tháng/Năm: 15/2/2020
Giá Vé: 450000
===> Tổng Tiền = 950000
- Thông Tin Khách Hàng:
Họ Tên: Nguyen Van B
Giới Tính: Nam
Tuổi: 21
- Thông Tin Chuyến Bay:
Tên Chuyến: Ha Noi - TP.Ho Chi Minh
Ngày Bay:
Ngày/Tháng/Năm: 20/2/2020
Giá Vé: 1500000
===> Tổng Tiền = 1500000
- Thông Tin Khách Hàng:
Họ Tên: Nguyen Thi C
Giới Tính: Nu
Tuổi: 19
- Thông Tin Chuyến Bay:
Tên Chuyến: Ha Noi - Da Nang
Ngày Bay:
Ngày/Tháng/Năm: 19/2/2020
Giá Vé: 1200000
Tên Chuyến: Ha Noi - Hue
Ngày Bay:
Ngày/Tháng/Năm: 18/2/2020
Giá Vé: 1250000
Tên Chuyến: Hue - Da Nang
Ngày Bay:
Ngày/Tháng/Năm: 22/2/2020
Giá Vé: 500000
===> Tổng Tiền = 2950000
After Sort:
- Thông Tin Khách Hàng:
Họ Tên: Nguyen Thi C
Giới Tính: Nu
Tuổi: 19
- Thông Tin Chuyến Bay:
Tên Chuyến: Ha Noi - Da Nang
Ngày Bay:
Ngày/Tháng/Năm: 19/2/2020
Giá Vé: 1200000
Tên Chuyến: Ha Noi - Hue
Ngày Bay:
Ngày/Tháng/Năm: 18/2/2020
Giá Vé: 1250000
Tên Chuyến: Hue - Da Nang
Ngày Bay:
Ngày/Tháng/Năm: 22/2/2020
Giá Vé: 500000
===> Tổng Tiền = 2950000
- Thông Tin Khách Hàng:
Họ Tên: Nguyen Van B
Giới Tính: Nam
Tuổi: 21
- Thông Tin Chuyến Bay:
Tên Chuyến: Ha Noi - TP.Ho Chi Minh
Ngày Bay:
Ngày/Tháng/Năm: 20/2/2020
Giá Vé: 1500000
===> Tổng Tiền = 1500000
- Thông Tin Khách Hàng:
Họ Tên: Nguyen Van A
Giới Tính: Nam
Tuổi: 20
- Thông Tin Chuyến Bay:
Tên Chuyến: Ha Noi - Hai Phong
Ngày Bay:
Ngày/Tháng/Năm: 10/2/2020
Giá Vé: 500000
Tên Chuyến: Hai Phong - Ha Noi
Ngày Bay:
Ngày/Tháng/Năm: 15/2/2020
Giá Vé: 450000
===> Tổng Tiền = 950000
Trong bài tập lập trình hướng đối tượng số 3 này, có một lưu ý nhỏ. Nếu không sắp xếp các hành khách theo tổng tiền, chúng ta có thể khai báo ve
là một con trỏ kiểu Vemaybay
. Tuy nhiên, khi thực hiện sắp xếp, chúng ta phải đổi chỗ các ô nhớ chứa hành khách. Nếu vẫn khai báo Vemaybay *ve
, nghĩa là ve
sẽ được lưu trong bộ nhớ chỉ đọc, khi đổi chỗ sẽ gây lỗi Segmentation Fault.
Bạn có thể xem thêm về lỗi này tại đây.
Bài tổng hợp các bài tập lập trình hướng đối tượng từ cơ bản đến nâng cao đã đến hồi kết. Cảm ơn tất cả mọi người đã ủng hộ trong suốt thời gian qua. Chúc mọi người mạnh khỏe và hẹn gặp lại trong những bài viết tiếp theo.