# 🌳 C++ Idioms & Concepts — Mastery Notes
## 📌 Overview
This series dives deep into modern C++ idioms to build a solid foundation in writing expressive, efficient, and idiomatic code.
---
## 📂 Copy-on-Write Idiom
### ✅ Intuition
Separate resource ownership from copy semantics. Avoid deep copies until a write is needed.
### 💡 Code Sketch
```cpp
class CowString {
private:
std::shared_ptr<std::string> data;
public:
CowString(const std::string& s) : data(std::make_shared<std::string>(s)) {}
void write(char c) {
if (!data.unique()) data = std::make_shared<std::string>(*data);
(*data)[0] = c;
}
};
Use STL's remove with erase to actually eliminate elements from containers.
remove worksMoves matching elements to the end and returns new logical end.
erase worksPhysically removes them from container.
v.erase(std::remove(v.begin(), v.end(), 5), v.end());
Prevent accidental copying/moving of resources.
=deleteclass NonCopyable {
public:
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
};
std::unique_ptrA class inherits from a base class template that takes the derived class as a parameter.
template<typename Derived>
class Base {
public:
void interface() {
static_cast<Derived*>(this)->implementation();
}
};
class Derived : public Base<Derived> {
public:
void implementation() {
std::cout << "Derived implementation
";
}
};
static_cast<Derived*>(this): downcast without runtime costclass Animal {
public:
virtual void speak() = 0;
};
class Dog : public Animal {
void speak() override { std::cout << "Woof!
"; }
};
template<typename Derived>
class Animal {
public:
void speak() { static_cast<Derived*>(this)->speak_impl(); }
};
class Dog : public Animal<Dog> {
public:
void speak_impl() { std::cout << "Woof!
"; }
};
Avoid virtual functions with template-based dispatch.
Encapsulate behavior in template base classes, used by multiple derived classes.
Auto-assign unique IDs or tags at compile time.
Add modular reusable functionality by composing CRTP classes.
Delay evaluation of expressions for performance in math libraries.
Make sure derived class implements certain methods.
Avoid runtime overhead while enforcing structure.
dynamic_cast<T*> for safe downcastingstatic_cast<T*> when you know the type (e.g. in CRTP)class A {
public:
virtual void foo() { std::cout << "A::foo
"; }
};
class B : public A {
public:
void foo() override { std::cout << "B::foo
"; }
};