private/public → thể hiện Tính đóng gói (Encapsulation): che giấu dữ liệu, chỉ cho truy cập qua phương thức publicPhanSo b = a; hoặc PhanSo b(a);<< và >> vì tham số bên trái là ostream/istream, không phải đối tượng của lớp// Nạp chồng << friend ostream& operator<<(ostream& os, const X& x); // Nạp chồng >> friend istream& operator>>(istream& is, X& x); // Nạp chồng = X& operator=(const X& other);
PhanSo b = a; (b chưa tồn tại)b = a; (b đã tồn tại từ trước)| Lớp cha | public | protected | private |
|---|---|---|---|
| public | public | protected | private |
| protected | protected | protected | private |
| private | Không truy cập được từ lớp con | ||
class B : virtual public A {}; class C : virtual public A {}; class D : public B, public C {}; // D chỉ có 1 bản sao duy nhất của A
Base* p = new Derived();dynamic_cast, trả về nullptr nếu thất bạiDerived* d = dynamic_cast<Derived*>(basePtr); if (d != nullptr) { // thành công }
virtual: cho phép lớp con ghi đèoverride (C++11): đánh dấu rõ ràng đang ghi đè, compiler kiểm trafinal (C++11): ngăn lớp con ghi đè hàm này / ngăn kế thừa lớp nàyvirtual void f() = 0; — không có thân hàm, bắt buộc lớp con phải ghi đèdelete con trỏ lớp cha trỏ đến lớp con:virtual ~Base() {} → gọi ~Derived() trước, rồi ~Base() → an toànclass Hinh { public: virtual ~Hinh() {} // BẮT BUỘC khi dùng đa hình virtual double TinhDienTich() = 0; }; int main() { Hinh* h = new HinhTron(5.0); // upcasting cout << h->TinhDienTich(); // đa hình delete h; // an toàn nhờ virtual destructor }
| Chữ | Tên | Ý nghĩa ngắn gọn |
|---|---|---|
| S | Single Responsibility | Mỗi lớp chỉ 1 trách nhiệm duy nhất |
| O | Open/Closed | Mở để mở rộng, đóng để sửa đổi |
| L | Liskov Substitution | Lớp con thay thế được lớp cha mà không làm sai |
| I | Interface Segregation | Chia nhỏ interface, không ép phụ thuộc thứ không cần |
| D | Dependency Inversion | Phụ thuộc trừu tượng, không phụ thuộc cụ thể |
// 1. Lớp trừu tượng AnPham class AnPham { protected: string maAnPham, tieuDe; double giaBan; public: AnPham(string ma, string td, double gia) : maAnPham(ma), tieuDe(td), giaBan(gia) {} virtual ~AnPham() {} // Virtual Destructor virtual void XuatThongTin() = 0; // Pure virtual }; // 2. Lớp Sach kế thừa AnPham class Sach : public AnPham { private: int soTrang; public: Sach(string ma, string td, double gia, int st) : AnPham(ma, td, gia), soTrang(st) {} void XuatThongTin() override { cout << maAnPham << " - " << tieuDe << " - " << giaBan << " - " << soTrang << endl; } // 3. Nạp chồng << và >> friend ostream& operator<<(ostream& os, const Sach& s) { os << s.maAnPham << " - " << s.tieuDe; return os; } friend istream& operator>>(istream& is, Sach& s) { is >> s.maAnPham >> s.tieuDe >> s.giaBan >> s.soTrang; return is; } }; // Lớp TapChi tương tự class TapChi : public AnPham { private: int thangPhatHanh; public: TapChi(string ma, string td, double gia, int thang) : AnPham(ma, td, gia), thangPhatHanh(thang) {} void XuatThongTin() override { cout << maAnPham << " - " << tieuDe << " - Tháng " << thangPhatHanh << endl; } }; // 4. Đa hình & Quản lý bộ nhớ int main() { AnPham* ds[3]; // Mảng con trỏ lớp cơ sở ds[0] = new Sach("S01", "C++", 50000, 300); // upcasting ds[1] = new TapChi("T01", "CNTT", 20000, 6); ds[2] = new Sach("S02", "OOP", 60000, 450); for (int i = 0; i < 3; i++) ds[i]->XuatThongTin(); // Đa hình động for (int i = 0; i < 3; i++) delete ds[i]; // An toàn nhờ virtual destructor return 0; }
50 câu hỏi trắc nghiệm - Kiểm tra kiến thức trước khi thi
Chọn chương muốn làm (hoặc tất cả):