initial commit

This commit is contained in:
dl92
2026-01-06 15:05:27 +00:00
parent a94f174a39
commit 62ab80b1d6
25 changed files with 1291 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
# Tutorial 2.1 Plan: Resource Management & The Rule of Zero
**Objective:** To master modern C++ resource management techniques, moving away from manual memory handling (`new`/`delete`) to the robust RAII (Resource Acquisition Is Initialization) idiom. This tutorial will demonstrate the "Rule of Zero" by refactoring a C++98-style class that requires manual memory management into a modern, safer equivalent using standard library containers and smart pointers.
---
## 1. Project Setup
To keep our tutorials organized, we will create a new directory for this lesson.
1. **Create a `tutorial-2` directory:** Inside the `GeminiTutorial` project root.
2. **Copy Configuration:** Copy the `CMakeLists.txt` and the `.vscode` directory from `tutorial-1` into the new `tutorial-2` directory. This preserves our build and debug configurations.
3. **Update `CMakeLists.txt`:** Modify the `project()` name at the top of `tutorial-2/CMakeLists.txt` from `Tutorial1` to `Tutorial2`.
---
## 2. The "Old Way": Manual Memory Management (The Rule of Three/Five)
First, we'll create a class that manually manages a dynamic array of doubles. This will highlight the complexity and risks of the C++98 approach.
**File:** `tutorial-2/src/StockData_Old.h`
```cpp
#pragma once // Use modern include guard
#include <cstddef> // For size_t
class StockData_Old {
public:
// Constructor
StockData_Old(size_t size);
// Copy Constructor (Rule 1 of 3)
StockData_Old(const StockData_Old& other);
// Copy Assignment Operator (Rule 2 of 3)
StockData_Old& operator=(const StockData_Old& other);
// Destructor (Rule 3 of 3)
~StockData_Old();
// Public method to access data
double& at(size_t index);
private:
double* data_;
size_t size_;
};
```
We will also create the corresponding `.cpp` file to implement these special member functions, demonstrating the need for deep copies and manual cleanup.
---
## 3. The "Modern Way": Automatic Resource Management (The Rule of Zero)
Next, we will create a modern equivalent that leverages `std::vector`. This class will achieve the same functionality with significantly less code and greater safety.
**File:** `tutorial-2/src/StockData_Modern.h`
```cpp
#pragma once
#include <vector>
class StockData_Modern {
public:
// Constructor
StockData_Modern(size_t size);
// No Copy Constructor, Copy Assignment, or Destructor needed!
// The compiler-generated versions work perfectly because `std::vector` handles itself.
// Public method to access data
double& at(size_t index);
private:
std::vector<double> data_;
};
```
This class adheres to the **Rule of Zero**, as it owns its resources through a standard library container and requires no custom resource management code.
---
## 4. Introducing Smart Pointers for Single Object Ownership
While containers are for sequences of objects, smart pointers manage the lifetime of a single dynamically allocated object.
1. **`std::unique_ptr`:** Represents exclusive ownership. The object is destroyed automatically when the `unique_ptr` goes out of scope.
2. **`std::shared_ptr`:** Represents shared ownership. The object is destroyed only when the last `shared_ptr` pointing to it is destroyed.
We will create a simple `Trade` class and a `main.cpp` to demonstrate creating and managing `Trade` objects on the heap using both `std::unique_ptr` and `std::shared_ptr`.
---
## 5. Updating the Build System and Main Application
We will modify `tutorial-2/CMakeLists.txt` to include all our new source files (`.cpp` files for `StockData_Old`, `StockData_Modern`, and the new `main.cpp`).
The `main.cpp` will first use `StockData_Old` to illustrate its usage (and potential pitfalls), then use `StockData_Modern` to show the simplicity and safety of the modern approach, and finally demonstrate the usage of smart pointers.
---
## 6. Summary and Key Takeaways
This tutorial will provide hands-on experience with the core principles of modern C++ resource management:
* **RAII:** Let objects manage resources. Acquisition is in the constructor, release is in the destructor.
* **Rule of Zero:** By using standard library classes like `std::vector`, `std::string`, `std::unique_ptr`, and `std::shared_ptr` to handle resource ownership, your own classes often don't need any custom destructor, copy/move constructors, or assignment operators.
* **Expressing Ownership:** Choose the right tool for the job:
* `std::vector` for owning a dynamic array of elements.
* `std::unique_ptr` for exclusive ownership of a single heap-allocated object.
* `std::shared_ptr` for shared ownership of a single heap-allocated object.