Phase 2: Lập Trình Hướng Đối Tượng trong Modern C++

Chào Mừng Đến Phase 2
Bạn đã thành thạo C++ fundamentals—types, functions, references, và compilation model. Bây giờ là lúc khám phá Lập Trình Hướng Đối Tượng trong C++. Khác với Java hay Python nơi OOP đơn giản, C++ cho bạn kiểm soát chi tiết về memory layout, object lifetime, và performance.
Phase này covers mọi thứ bạn cần để xây dựng C++ classes vững chắc: constructors, destructors, Rule of Five (và khi nào dùng Rule of Zero), inheritance, polymorphism, và operator overloading. Chúng ta sẽ nhấn mạnh RAII (Resource Acquisition Is Initialization)—idiom nền tảng C++ giúp quản lý resource an toàn và tự động.
Thời gian: 1-2 tuần, 1-2 giờ mỗi ngày Yêu cầu trước: Phase 1: C++ Fundamentals
Bạn Sẽ Học Được
✅ Thiết kế classes với proper encapsulation
✅ Viết tất cả special member functions
✅ Hiểu RAII và áp dụng cho resource management
✅ Sử dụng inheritance và virtual functions đúng cách
✅ Implement polymorphic hierarchies
✅ Overload operators cho custom types
✅ Áp dụng modern C++ idioms (= default, = delete, override, final)
1. Classes và Objects
Cú Pháp Định Nghĩa Class
class Rectangle {
private: // Access specifier (default cho class)
double width_;
double height_;
public:
// Constructor
Rectangle(double width, double height)
: width_{width}, height_{height} {}
// Member functions
double area() const {
return width_ * height_;
}
// Getters và Setters
double width() const { return width_; }
void set_width(double w) { width_ = w; }
};Điểm quan trọng:
- Access specifiers:
private,public,protected - Member initializer list:
: width_{width}(ưu tiên hơn assignment) constmember functions: Hứa không modify object state
struct vs class
Sự khác biệt duy nhất: default access.
class MyClass {
int x; // private by default
};
struct MyStruct {
int x; // public by default
};2. Constructors
Default Constructor
class Point {
private:
double x_, y_;
public:
// Default constructor
Point() : x_{0.0}, y_{0.0} {}
// Parameterized constructor
Point(double x, double y) : x_{x}, y_{y} {}
};= default và = delete
class Widget {
public:
Widget() = default; // Compiler tạo default constructor
Widget(int value); // Custom constructor
// Ngăn copying
Widget(const Widget&) = delete;
Widget& operator=(const Widget&) = delete;
};Member Initializer Lists
Luôn ưu tiên initializer lists hơn assignment:
class GoodExample {
private:
std::string name_;
int count_;
public:
GoodExample(const std::string& name, int count)
: name_{name}, count_{count} {} // Direct initialization
};explicit Keyword
Ngăn implicit conversions:
class Kilometer {
public:
explicit Kilometer(double v) : value_{v} {}
};
// Kilometer k = 5.0; // ERROR: không implicit conversion
Kilometer k{5.0}; // OK: explicit construction3. Destructors và RAII
RAII: Resource Acquisition Is Initialization
RAII là idiom quan trọng nhất trong C++: gắn resource lifetime với object lifetime.
class FileHandle {
private:
FILE* file_;
public:
explicit FileHandle(const char* filename, const char* mode) {
file_ = std::fopen(filename, mode);
if (!file_) {
throw std::runtime_error("Failed to open file");
}
}
~FileHandle() {
if (file_) {
std::fclose(file_); // Luôn được cleanup!
}
}
// Ngăn copying
FileHandle(const FileHandle&) = delete;
FileHandle& operator=(const FileHandle&) = delete;
};Tại sao RAII mạnh:
- Không leak: Destructor luôn chạy (kể cả với exceptions)
- Không quên đóng: Cleanup tự động
- Composable: RAII objects có thể chứa RAII objects khác
4. Copy và Move Semantics
Copy Constructor và Assignment
class IntArray {
private:
int* data_;
size_t size_;
public:
// Copy constructor
IntArray(const IntArray& other)
: data_{new int[other.size_]}, size_{other.size_} {
std::copy(other.data_, other.data_ + size_, data_);
}
// Copy assignment operator
IntArray& operator=(const IntArray& other) {
if (this != &other) {
delete[] data_;
size_ = other.size_;
data_ = new int[size_];
std::copy(other.data_, other.data_ + size_, data_);
}
return *this;
}
};Move Semantics
class IntArray {
public:
// Move constructor
IntArray(IntArray&& other) noexcept
: data_{other.data_}, size_{other.size_} {
other.data_ = nullptr;
other.size_ = 0;
}
// Move assignment
IntArray& operator=(IntArray&& other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
size_ = other.size_;
other.data_ = nullptr;
other.size_ = 0;
}
return *this;
}
};Rule of Five và Rule of Zero
Rule of Five: Nếu định nghĩa một trong những hàm sau, bạn có thể cần định nghĩa tất cả:
- Destructor
- Copy constructor
- Copy assignment operator
- Move constructor
- Move assignment operator
Rule of Zero: Thiết kế classes để compiler-generated defaults đúng (dùng RAII types).
5. Inheritance
Basic Inheritance
class Animal {
protected:
std::string name_;
public:
Animal(std::string name) : name_{std::move(name)} {}
void eat() const { std::cout << name_ << " is eating\n"; }
};
class Dog : public Animal {
public:
Dog(std::string name) : Animal{std::move(name)} {}
void bark() const { std::cout << name_ << " says: Woof!\n"; }
};Thứ Tự Constructor/Destructor
Khởi tạo: Base() → Derived()
Hủy: ~Derived() → ~Base()6. Polymorphism
Virtual Functions
class Shape {
public:
virtual double area() const = 0; // Pure virtual
virtual ~Shape() = default; // QUAN TRỌNG: virtual destructor
};
class Circle : public Shape {
private:
double radius_;
public:
explicit Circle(double r) : radius_{r} {}
double area() const override {
return 3.14159 * radius_ * radius_;
}
};Virtual Destructors
Quy tắc quan trọng: Nếu class có virtual functions, cần virtual destructor.
class Base {
public:
virtual void foo() {}
virtual ~Base() = default; // ĐÚNG
};override và final
class Derived : public Base {
public:
void foo() const override; // Đảm bảo đang override
void bar() final; // Không thể override thêm
};
class FinalClass final : public Base {
// Không thể kế thừa từ class này
};7. Operator Overloading
class Fraction {
private:
int numerator_;
int denominator_;
public:
Fraction(int num, int den = 1)
: numerator_{num}, denominator_{den} {}
// Arithmetic operators
Fraction operator+(const Fraction& other) const {
return Fraction{
numerator_ * other.denominator_ + other.numerator_ * denominator_,
denominator_ * other.denominator_
};
}
// Comparison (C++20)
auto operator<=>(const Fraction& other) const {
return (numerator_ * other.denominator_) <=>
(other.numerator_ * denominator_);
}
};
// Stream operator (non-member)
std::ostream& operator<<(std::ostream& os, const Fraction& f) {
return os << f.numerator() << '/' << f.denominator();
}8. Multiple Inheritance và Diamond Problem
Virtual Inheritance
Giải quyết diamond problem:
class Animal {
public:
std::string name;
};
class Mammal : virtual public Animal {};
class Bird : virtual public Animal {};
class Bat : public Mammal, public Bird {
// Chỉ có MỘT Animal subobject
};Lời khuyên: Tránh multiple inheritance của classes. Ưu tiên:
- Single inheritance với interfaces (pure abstract classes)
- Composition over inheritance
9. Các Lỗi Thường Gặp
1. Slicing
void badFunction(Base b) { // Pass by VALUE = slicing!
b.foo(); // Luôn gọi Base::foo()
}Fix: Pass polymorphic types bằng reference hoặc pointer.
2. Quên Virtual Destructor
Luôn làm destructors virtual trong base classes.
3. Gọi Virtual Functions trong Constructor/Destructor
Virtual dispatch không hoạt động như mong đợi trong constructors.
Tóm Tắt
✅ Classes: Dùng access specifiers, prefer struct cho data, class cho behavior
✅ Constructors: Dùng initializer lists, explicit cho single-arg
✅ RAII: Gắn resource lifetime với object lifetime
✅ Rule of Five/Zero: Định nghĩa tất cả năm, hoặc không định nghĩa gì
✅ Inheritance: Dùng public inheritance, luôn virtual destructors
✅ Polymorphism: Dùng override, pass by reference/pointer
✅ Composition: Ưu tiên composition hơn inheritance
Tiếp Theo
- Phase 3: Modern C++ Features → — C++11 đến C++23 features
- Deep Dive: Memory Management → — RAII chi tiết
Tài Liệu Bổ Sung
Series: Modern C++ Learning Roadmap
Trước: Phase 1: C++ Fundamentals
Tiếp: Phase 3: Modern C++ Features
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.