Experiment 1: GradeCalc
1 #pragma once
2
3 #include <vector>
4 #include <array>
5 #include <string>
6
7 class GradeCalc {
8 public:
9 GradeCalc(const std::string &ten_khoa_hoc);
10 void nhap(int so_luong); // Nhập số_luong điểm
11 void xuat() const; // Xuất các điểm
12 void sap_xep(bool tang_dan = false); // Sắp xếp (mặc định giảm dần)
13 int min() const; // Trả về điểm thấp nhất
14 int max() const; // Trả về điểm cao nhất
15 double trung_binh() const; // Trả về trung bình
16 void thong_tin(); // Xuất thông tin về điểm của khóa học
17
18 private:
19 void tinh_toan(); // Tính toán các thống kê điểm
20
21 private:
22 std::string ten_khoa_hoc; // Tên khóa học
23 std::vector<int> diem; // Điểm của khóa học
24 std::array<int, 5> so_luong_diem; // Số người trong từng đoạn điểm
25 std::array<double, 5> phan_tram; // Tỷ lệ phần trăm trong từng đoạn
26 bool danh dau; // Danh dấu cho biết thông tin đã được cập nhật
27 };
GradeCalc.cpp:
1 #include <algorithm>
2 #include <array>
3 #include <cstdlib>
4 #include <iomanip>
5 #include <iostream>
6 #include <numeric>
7 #include <string>
8 #include <vector>
9 #include "GradeCalc.hpp"
10
11 GradeCalc::GradeCalc(const std::string& ten_khoa_hoc) : ten_khoa_hoc{ten_khoa_hoc}, danh_dau{true} {
12 so_luong_diem.fill(0);
13 phan_tram.fill(0.0);
14 }
15
16 void GradeCalc::nhap(int so_luong) {
17 if (so_luong < 0) {
18 std::cerr << "Nhập không hợp lệ! Số lượng không thể là số âm.\n";
19 return;
20 }
21
22 diem.reserve(so_luong);
23 int diem_so;
24 for (int i = 0; i < so_luong;) {
25 std::cin >> diem_so;
26 if (diem_so < 0 || diem_so > 100) {
27 std::cerr << "Nhập không hợp lệ! Điểm phải trong khoảng [0, 100].\n";
28 continue;
29 }
30 diem.push_back(diem_so);
31 ++i;
32 }
33 danh_dau = true;
34 }
35
36 void GradeCalc::xuat() const {
37 for (auto diem : diem) {
38 std::cout << diem << ' ';
39 }
40 std::cout << std::endl;
41 }
42
43 void GradeCalc::sap_xep(bool tang_dan) {
44 if (tang_dan) {
45 std::sort(diem.begin(), diem.end());
46 } else {
47 std::sort(diem.begin(), diem.end(), std::greater<int>());
48 }
49 }
50
51 int GradeCalc::min() const {
52 if (diem.empty()) return -1;
53 auto it = std::min_element(diem.begin(), diem.end());
54 return *it;
55 }
56
57 int GradeCalc::max() const {
58 if (diem.empty()) return -1;
59 auto it = std::max_element(diem.begin(), diem.end());
60 return *it;
61 }
62
63 double GradeCalc::trung_binh() const {
64 if (diem.empty()) return 0.0;
65 double tb = std::accumulate(diem.begin(), diem.end(), 0.0) / diem.size();
66 return tb;
67 }
68
69 void GradeCalc::thong_tin() {
70 if (danh_dau) tinh_toan();
71 std::cout << "Tên khóa học:\t" << ten_khoa_hoc << std::endl;
72 std::cout << "Trung bình:\t" << std::fixed << std::setprecision(2) << trung_binh() << std::endl;
73 std::cout << "Điểm cao nhất:\t" << max() << std::endl;
74 std::cout << "Điểm thấp nhất:\t" << min() << std::endl;
75 }
76
77 void GradeCalc::tinh_toan() {
78 if (diem.empty()) return;
79 so_luong_diem.fill(0);
80 phan_tram.fill(0.0);
81 for (int diem_so : diem) {
82 if (diem_so < 60) ++so_luong_diem[0];
83 else if (diem_so < 70) ++so_luong_diem[1];
84 else if (diem_so < 80) ++so_luong_diem[2];
85 else if (diem_so < 90) ++so_luong_diem[3];
86 else ++so_luong_diem[4];
87 }
88 for (size_t i = 0; i < so_luong_diem.size(); ++i) {
89 phan_tram[i] = so_luong_diem[i] * 1.0 / diem.size();
90 }
91 danh_dau = false;
92 }
Task1.cpp:
1 #include <iostream>
2 #include <string>
3 #include "GradeCalc.hpp"
4
5 void test() {
6 GradeCalc bc("Toan");
7 std::cout << "Nhap diem:\n";
8 bc.nhap(5);
9 std::cout << "Xuat diem:\n";
10 bc.xuat();
11 std::cout << "Sap xep diem:\n";
12 bc.sap_xep();
13 bc.xuat();
14 std::cout << "*************Thong tin diem*************\n";
15 bc.thong_tin();
16 }
17
18 int main() {
19 test();
20 }
Experiment 2: Inheritance vs Composition
1 #pragma once
2
3 #include <array>
4 #include <string>
5 #include <vector>
6
7 class GradeCalc : private std::vector<int> {
8 public:
9 GradeCalc(const std::string &ten_khoa_hoc);
10 void nhap(int so_luong); // Nhập số_luong điểm
11 void xuat() const; // Xuất các điểm
12 void sap_xep(bool tang_dan = false); // Sắp xếp (mặc định giảm dần)
13 int min() const; // Trả về điểm thấp nhất
14 int max() const; // Trả về điểm cao nhất
15 double trung_binh() const; // Trả về trung bình
16 void thong_tin(); // Xuất thông tin về điểm của khóa học
17
18 private:
19 void tinh_toan(); // Tính toán các thống kê điểm
20
21 private:
22 std::string ten_khoa_hoc; // Tên khóa học
23 std::array<int, 5> so_luong_diem; // Số người trong từng đoạn điểm
24 std::array<double, 5> phan_tram; // Tỷ lệ phần trăm trong từng đoạn
25 bool danh_dau; // Danh dấu cho biết thông tin đã được cập nhật
26 };
GradeCalc.cpp:
1 #include <algorithm>
2 #include <array>
3 #include <cstdlib>
4 #include <iomanip>
5 #include <iostream>
6 #include <numeric>
7 #include <string>
8 #include <vector>
9 #include "GradeCalc.hpp"
10
11 GradeCalc::GradeCalc(const std::string& ten_khoa_hoc) : ten_khoa_hoc(ten_khoa_hoc), danh_dau(true) {
12 so_luong_diem.fill(0);
13 phan_tram.fill(0.0);
14 }
15
16 void GradeCalc::nhap(int so_luong) {
17 if (so_luong < 0) {
18 std::cerr << "Nhập không hợp lệ! Số lượng không thể là số âm.\n";
19 return;
20 }
21 this->reserve(so_luong);
22 int diem_so;
23 for (int i = 0; i < so_luong;) {
24 std::cin >> diem_so;
25 if (diem_so < 0 || diem_so > 100) {
26 std::cerr << "Nhập không hợp lệ! Điểm phải trong khoảng [0, 100].\n";
27 continue;
28 }
29 this->push_back(diem_so);
30 ++i;
31 }
32 danh_dau = true;
33 }
34
35 void GradeCalc::xuat() const {
36 for (auto diem : *this) {
37 std::cout << diem << ' ';
38 }
39 std::cout << std::endl;
40 }
41
42 void GradeCalc::sap_xep(bool tang_dan) {
43 if (tang_dan) {
44 std::sort(this->begin(), this->end());
45 } else {
46 std::sort(this->begin(), this->end(), std::greater<int>());
47 }
48 }
49
50 int GradeCalc::min() const {
51 if (this->empty()) return -1;
52 return *std::min_element(this->begin(), this->end());
53 }
54
55 int GradeCalc::max() const {
56 if (this->empty()) return -1;
57 return *std::max_element(this->begin(), this->end());
58 }
59
60 double GradeCalc::trung_binh() const {
61 if (this->empty()) return 0.0;
62 double tb = std::accumulate(this->begin(), this->end(), 0.0) / this->size();
63 return tb;
64 }
65
66 void GradeCalc::thong_tin() {
67 if (danh_dau) tinh_toan();
68 std::cout << "Tên khóa học:\t" << ten_khoa_hoc << std::endl;
69 std::cout << "Trung bình:\t" << std::fixed << std::setprecision(2) << trung_binh() << std::endl;
70 std::cout << "Điểm cao nhất:\t" << max() << std::endl;
71 std::cout << "Điểm thấp nhất:\t" << min() << std::endl;
72 }
73
74 void GradeCalc::tinh_toan() {
75 if (this->empty()) return;
76 so_luong_diem.fill(0);
77 phan_tram.fill(0.0);
78 for (int diem_so : *this) {
79 if (diem_so < 60) ++so_luong_diem[0];
80 else if (diem_so < 70) ++so_luong_diem[1];
81 else if (diem_so < 80) ++so_luong_diem[2];
82 else if (diem_so < 90) ++so_luong_diem[3];
83 else ++so_luong_diem[4];
84 }
85 for (size_t i = 0; i < phan_tram.size(); ++i) {
86 phan_tram[i] = so_luong_diem[i] * 1.0 / this->size();
87 }
88 danh_dau = false;
89 }
Experiment 3: Polymorphism with Shapes
1 #pragma once
2
3 #include <string>
4 #include <vector>
5
6 enum class Hinh { tron, tam_giac, hinh_vuong };
7
8 class Hinh {
9 public:
10 virtual void ve() = 0;
11 virtual ~Hinh() = default;
12 };
13
14 class Tron : public Hinh {
15 public:
16 void ve() override;
17 };
18
19 class TamGiac : public Hinh {
20 public:
21 void ve() override;
22 };
23
24 class HinhVuong : public Hinh {
25 public:
26 void ve() override;
27 };
28
29 class BanVinh {
30 public:
31 void them(const std::string& loai_hinh);
32 void ve_tat_ca() const;
33 ~BanVinh();
34
35 private:
36 std::vector<Hinh*> hinh;
37 };
38
39 Hinh* tao_hinh(const std::string& loai);
40 Hinh::HinhType str_to_HinhType(const std::string& s);
Hinh.cpp:
1 #include <algorithm>
2 #include <cctype>
3 #include <iostream>
4 #include <string>
5
6 #include "Hinh.hpp"
7
8 void Tron::ve() { std::cout << "Vẽ một hình tròn...\n"; }
9 void TamGiac::ve() { std::cout << "Vẽ một tam giác...\n"; }
10 void HinhVuong::ve() { std::cout << "Vẽ một hình vuông...\n"; }
11
12 void BanVinh::them(const std::string& loai_hinh) {
13 Hinh* h = tao_hinh(loai_hinh);
14 if (h) hinh.push_back(h);
15 }
16
17 void BanVinh::ve_tat_ca() const {
18 for (Hinh* h : hinh) h->ve();
19 }
20
21 BanVinh::~BanVinh() {
22 for (Hinh* h : hinh) delete h;
23 }
24
25 Hinh* tao_hinh(const std::string& loai) {
26 switch (str_to_HinhType(loai)) {
27 case Hinh::tron: return new Tron;
28 case Hinh::tam_giac: return new TamGiac;
29 case Hinh::hinh_vuong: return new HinhVuong;
30 default: return nullptr;
31 }
32 }
33
34 Hinh::HinhType str_to_HinhType(const std::string& s) {
35 std::string t = s;
36 std::transform(s.begin(), s.end(), t.begin(), [](unsigned char c) { return std::tolower(c); });
37 if (t == "tron") return Hinh::tron;
38 if (t == "tam_giac") return Hinh::tam_giac;
39 if (t == "hinh_vuong") return Hinh::hinh_vuong;
40 return Hinh::tron;
41 }
Experiment 4: Toy Factory
1 #ifndef CAYXUCXICH_HPP
2 #define CAYXUCXICH_HPP
3
4 #include <string>
5
6 class CayXucXich {
7 protected:
8 std::string ten;
9 std::string material;
10 std::string loai;
11 std::string am_thanh;
12
13 public:
14 CayXucXich(const std::string& n, const std::string& m, const std::string& t, const std::string& s);
15 virtual ~CayXucXich() = default;
16
17 virtual void hoat_dong() const = 0;
18 void phat_am_thanh() const;
19 void hien_thi_thong_tin() const;
20 std::string getTen() const;
21 std::string getMaterial() const;
22 std::string getLoai() const;
23 std::string getAmThanh() const;
24 };
25
26 #endif
CayXucXich.cpp:
1 #include "CayXucXich.hpp"
2 #include <iostream>
3
4 CayXucXich::CayXucXich(const std::string& n, const std::string& m, const std::string& t, const std::string& s)
5 : ten(n), material(m), loai(t), am_thanh(s) {}
6
7 void CayXucXich::phat_am_thanh() const {
8 std::cout << "Phát tiếng: " << am_thanh << std::endl;
9 }
10
11 void CayXucXich::hien_thi_thong_tin() const {
12 std::cout << ten << "\t" << material << "\t" << loai << "\t" << am_thanh << std::endl;
13 }
14
15 std::string CayXucXich::getTen() const { return ten; }
16 std::string CayXucXich::getMaterial() const { return material; }
17 std::string CayXucXich::getLoai() const { return loai; }
18 std::string CayXucXich::getAmThanh() const { return am_thanh; }
Factory Implementation
1 #ifndef TOYFACTORY_HPP
2 #define TOYFACTORY_HPP
3
4 #include <vector>
5 #include <string>
6 #include "CayXucXich.hpp"
7
8 class CayXucXichFactory {
9 private:
10 std::vector<CayXucXich*> cay;
11
12 public:
13 ~CayXucXichFactory();
14
15 bool them_cay(CayXucXich* c);
16 bool xoa_cay(const std::string& ten);
17
18 void hien_thi_tat_ca() const;
19 void phat_tat_ca_am_thanh() const;
20 void thuc_hien_tat_ca_hoat_dong() const;
21
22 int getSoLuongCay() const;
23 };
24
25 #endif
CayXucXichFactory.cpp:
1 #include "CayXucXichFactory.hpp"
2 #include <iostream>
3 #include <algorithm>
4
5 CayXucXichFactory::~CayXucXichFactory() {
6 for (CayXucXich* c : cay) {
7 delete c;
8 }
9 }
10
11 bool CayXucXichFactory::them_cay(CayXucXich* c) {
12 cay.push_back(c);
13 std::cout << "Thành công thêm cay: " << c->getTen() << std::endl;
14 return true;
15 }
16
17 bool CayXucXichFactory::xoa_cay(const std::string& ten) {
18 for (auto it = cay.begin(); it != cay.end(); ++it) {
19 if ((*it)->getTen() == ten) {
20 delete *it;
21 cay.erase(it);
22 std::cout << "Xóa thành công.\n";
23 return true;
24 }
25 }
26 return false;
27 }
28
29 void CayXucXichFactory::hien_thi_tat_ca() const {
30 std::cout << "Thông tin về các cay:" << std::endl;
31 for (const CayXucXich* c : cay) {
32 c->hien_thi_thong_tin();
33 }
34 }
35
36 void CayXucXichFactory::phat_tat_ca_am_thanh() const {
37 for (const CayXucXich* c : cay) {
38 c->phat_am_thanh();
39 }
40 }
41
42 void CayXucXichFactory::thuc_hien_tat_ca_hoat_dong() const {
43 for (const CayXucXich* c : cay) {
44 c->hoat_dong();
45 }
46 }
47
48 int CayXucXichFactory::getSoLuongCay() const {
49 return cay.size();
50 }