[2026] C++ Smart Pointers: unique_ptr, shared_ptr & Memory-Safe Patterns

[2026] C++ Smart Pointers: unique_ptr, shared_ptr & Memory-Safe Patterns

이 글의 핵심

C++ smart pointers explained: unique_ptr for exclusive ownership, shared_ptr for shared ownership, weak_ptr for cycles—examples, make_unique/make_shared, and production tips.

Introduction

Smart pointers are RAII-style wrappers that provide automatic memory management. They help avoid leaks and dangling pointers from raw new/delete. 다음은 cpp를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// ❌ Raw pointer (unsafe)
int* ptr = new int(10);  // Allocate on heap
// ....use ...
delete ptr;  // Manual delete (forget it → leak!)
// Issues:
// 1. Forgetting delete → leak
// 2. Exception may skip delete
// 3. Double delete → crash
// 4. Use after delete → UB (dangling)
// ✅ Smart pointer (safe)
// std::make_unique: factory for unique_ptr
// RAII: acquire in constructor, release in destructor
std::unique_ptr<int> ptr = std::make_unique<int>(10);
// delete runs automatically at end of scope
// Still safe if exceptions occur

1. unique_ptr — exclusive ownership

Basic usage

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
int main() {
    // Create
    std::unique_ptr<int> ptr = std::make_unique<int>(10);
    
    // Use
    std::cout << *ptr << std::endl;  // 10
    *ptr = 20;
    std::cout << *ptr << std::endl;  // 20
    
    // nullptr check
    if (ptr) {
        std::cout << "valid" << std::endl;
    }
    
    // Array
    std::unique_ptr<int[]> arr = std::make_unique<int[]>(5);
    arr[0] = 1;
    arr[1] = 2;
    std::cout << arr[0] << ", " << arr[1] << std::endl;  // 1, 2
    
    return 0;
}  // automatic delete

Move only (no copy)

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
// Pass by value: transfer ownership
// Memory freed when function returns
void process(std::unique_ptr<int> ptr) {
    std::cout << "value: " << *ptr << std::endl;
}  // ptr destroyed → memory freed
int main() {
    std::unique_ptr<int> ptr1 = std::make_unique<int>(10);
    
    // ❌ No copy: unique_ptr is exclusive
    // std::unique_ptr<int> ptr2 = ptr1;  // compile error
    // Copy constructor is deleted
    
    // ✅ Move: transfer ownership with std::move
    // Ownership moves from ptr1 to ptr2
    // After move, ptr1 is nullptr
    std::unique_ptr<int> ptr2 = std::move(ptr1);
    
    // Check ptr1
    if (!ptr1) {
        std::cout << "ptr1 is nullptr" << std::endl;
    }
    // Check ptr2
    if (ptr2) {
        std::cout << "ptr2 valid: " << *ptr2 << std::endl;
    }
    
    // Pass to function: transfer ownership
    // std::move(ptr2) transfers ownership into process
    // After call, ptr2 is nullptr
    process(std::move(ptr2));
    
    if (!ptr2) {
        std::cout << "ptr2 also nullptr" << std::endl;
    }
    
    return 0;
}

Output: 다음은 간단한 code 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

ptr1 is nullptr
ptr2 valid: 10
value: 10
ptr2 also nullptr

2. shared_ptr — shared ownership

Basic usage

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
int main() {
    // std::make_shared: preferred way to make shared_ptr
    // One allocation for control block + object (efficient)
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10);
    // use_count(): current reference count
    std::cout << "ref count: " << ptr1.use_count() << std::endl;  // 1
    
    {
        // shared_ptr copies: ref count increases
        // ptr1 and ptr2 share the same object
        std::shared_ptr<int> ptr2 = ptr1;  // copy ok
        // Ref count 2: two owners
        std::cout << "ref count: " << ptr1.use_count() << std::endl;  // 2
        std::cout << "ptr1: " << *ptr1 << std::endl;  // 10
        std::cout << "ptr2: " << *ptr2 << std::endl;  // 10
    }  // ptr2 destroyed → count 2 → 1
       // ptr1 still alive → storage kept
    
    std::cout << "ref count: " << ptr1.use_count() << std::endl;  // 1
    
    return 0;
}  // ptr1 destroyed → count 0 → freed

Output: 아래 코드는 code를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

ref count: 1
ref count: 2
ptr1: 10
ptr2: 10
ref count: 1

Reference counting

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
#include <vector>
class Resource {
public:
    Resource(int id) : id_(id) {
        std::cout << "Resource " << id_ << " created" << std::endl;
    }
    
    ~Resource() {
        std::cout << "Resource " << id_ << " destroyed" << std::endl;
    }
    
    int getId() const { return id_; }
    
private:
    int id_;
};
int main() {
    std::vector<std::shared_ptr<Resource>> resources;
    
    {
        auto r1 = std::make_shared<Resource>(1);
        resources.push_back(r1);
        resources.push_back(r1);
        resources.push_back(r1);
        
        std::cout << "ref count: " << r1.use_count() << std::endl;  // 4
    }  // r1 gone but vector still holds refs
    
    std::cout << "vector size: " << resources.size() << std::endl;  // 3
    std::cout << "ref count: " << resources[0].use_count() << std::endl;  // 3
    
    resources.clear();  // drop refs → destroy Resource
    
    return 0;
}

Output: 아래 코드는 code를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

Resource 1 created
ref count: 4
vector size: 3
ref count: 3
Resource 1 destroyed

3. weak_ptr — breaking circular references

The circular reference problem

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
class B;
class A {
public:
    std::shared_ptr<B> b_ptr;
    ~A() { std::cout << "A destroyed" << std::endl; }
};
class B {
public:
    std::shared_ptr<A> a_ptr;  // circular ref!
    ~B() { std::cout << "B destroyed" << std::endl; }
};
int main() {
    {
        std::shared_ptr<A> a = std::make_shared<A>();
        std::shared_ptr<B> b = std::make_shared<B>();
        
        a->b_ptr = b;
        b->a_ptr = a;  // circular reference
        
        std::cout << "a ref count: " << a.use_count() << std::endl;  // 2
        std::cout << "b ref count: " << b.use_count() << std::endl;  // 2
    }  // a,b dtor never runs — not freed!
    
    std::cout << "block end" << std::endl;
    
    return 0;
}

Output:

a ref count: 2
b ref count: 2
block end

Problem: A and B destructors never run (leak).

Fixing it with weak_ptr

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
class B;
class A {
public:
    std::shared_ptr<B> b_ptr;
    ~A() { std::cout << "A destroyed" << std::endl; }
};
class B {
public:
    std::weak_ptr<A> a_ptr;  // use weak_ptr
    ~B() { std::cout << "B destroyed" << std::endl; }
};
int main() {
    {
        std::shared_ptr<A> a = std::make_shared<A>();
        std::shared_ptr<B> b = std::make_shared<B>();
        
        a->b_ptr = b;
        b->a_ptr = a;  // weak_ptr does not bump strong count
        
        std::cout << "a ref count: " << a.use_count() << std::endl;  // 1
        std::cout << "b ref count: " << b.use_count() << std::endl;  // 2
    }  // A and B destroy normally
    
    std::cout << "block end" << std::endl;
    
    return 0;
}

Output: 아래 코드는 code를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

a ref count: 1
b ref count: 2
B destroyed
A destroyed
block end

Using weak_ptr

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
int main() {
    // weak_ptr: non-owning weak reference
    std::weak_ptr<int> weak;
    
    {
        // create shared_ptr
        std::shared_ptr<int> shared = std::make_shared<int>(42);
        // assign to weak_ptr: no strong count bump
        // does not extend shared lifetime
        weak = shared;
        
        // strong count still 1
        std::cout << "shared ref count: " << shared.use_count() << std::endl;  // 1
        
        // use weak_ptr: get shared_ptr via lock()
        // lock(): shared if alive, else nullptr
        if (auto locked = weak.lock()) {
            // locked: temporary shared (count++)
            std::cout << "value: " << *locked << std::endl;  // 42
            // ref count 2: shared + locked
            std::cout << "ref count: " << locked.use_count() << std::endl;  // 2
        }  // locked destroyed → back to 1
    }  // shared gone → count 0 → freed
    
    // check weak_ptr expiry
    // expired(): was object destroyed?
    if (weak.expired()) {
        std::cout << "weak_ptr expired" << std::endl;
    }
    
    // lock() on expired weak_ptr
    if (auto locked = weak.lock()) {
        std::cout << "value: " << *locked << std::endl;
    } else {
        // object gone — lock fails
        std::cout << "lock failed" << std::endl;
    }
    
    return 0;
}

Output: 아래 코드는 code를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

shared ref count: 1
value: 42
ref count: 2
weak_ptr expired
lock failed

4. Practical examples

Example 1: Resource management

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며, 비동기 처리를 통해 효율적으로 작업을 수행합니다, 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
#include <fstream>
class FileHandler {
private:
    std::unique_ptr<std::ofstream> file;
    std::string filename;
    
public:
    FileHandler(const std::string& filename) : filename(filename) {
        file = std::make_unique<std::ofstream>(filename);
        if (!file->is_open()) {
            throw std::runtime_error("failed to open file: " + filename);
        }
        std::cout << "file opened: " << filename << std::endl;
    }
    
    ~FileHandler() {
        if (file && file->is_open()) {
            file->close();
            std::cout << "file closed: " << filename << std::endl;
        }
    }
    
    void write(const std::string& data) {
        if (file && file->is_open()) {
            *file << data << std::endl;
        }
    }
};
int main() {
    try {
        FileHandler handler("output.txt");
        handler.write("Hello");
        handler.write("World");
        // file still closed on exception
    } catch (const std::exception& e) {
        std::cerr << "error: " << e.what() << std::endl;
    }
    
    return 0;
}

Example 2: Factory pattern

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
#include <string>
class Animal {
public:
    virtual void speak() = 0;
    virtual ~Animal() {}
};
class Dog : public Animal {
public:
    void speak() override {
        std::cout << "Woof!" << std::endl;
    }
    ~Dog() {
        std::cout << "Dog destroyed" << std::endl;
    }
};
class Cat : public Animal {
public:
    void speak() override {
        std::cout << "Meow!" << std::endl;
    }
    ~Cat() {
        std::cout << "Cat destroyed" << std::endl;
    }
};
std::unique_ptr<Animal> createAnimal(const std::string& type) {
    if (type == "dog") {
        return std::make_unique<Dog>();
    } else if (type == "cat") {
        return std::make_unique<Cat>();
    }
    return nullptr;
}
int main() {
    auto animal1 = createAnimal("dog");
    if (animal1) {
        animal1->speak();
    }
    
    auto animal2 = createAnimal("cat");
    if (animal2) {
        animal2->speak();
    }
    
    auto animal3 = createAnimal("bird");
    if (!animal3) {
        std::cout << "unknown animal" << std::endl;
    }
    
    return 0;
}

Output: 아래 코드는 code를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

Woof!
Meow!
unknown animal
Cat destroyed
Dog destroyed

Example 3: Cache (shared_ptr)

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <unordered_map>
#include <iostream>
#include <string>
class Resource {
private:
    std::string name;
    
public:
    Resource(std::string n) : name(n) {
        std::cout << "load resource: " << name << std::endl;
    }
    
    ~Resource() {
        std::cout << "unload resource: " << name << std::endl;
    }
    
    void use() {
        std::cout << name << " in use" << std::endl;
    }
    
    std::string getName() const { return name; }
};
class ResourceCache {
private:
    std::unordered_map<std::string, std::shared_ptr<Resource>> cache;
    
public:
    std::shared_ptr<Resource> getResource(const std::string& name) {
        if (cache.find(name) == cache.end()) {
            cache[name] = std::make_shared<Resource>(name);
        }
        return cache[name];
    }
    
    void printCacheSize() {
        std::cout << "cache size: " << cache.size() << std::endl;
    }
    
    void clear() {
        cache.clear();
        std::cout << "cache cleared" << std::endl;
    }
};
int main() {
    ResourceCache cache;
    
    {
        auto r1 = cache.getResource("texture1");
        auto r2 = cache.getResource("texture1");  // same object
        r1->use();
        
        std::cout << "r1 ref count: " << r1.use_count() << std::endl;  // 3 (r1, r2, cache)
        std::cout << "r2 ref count: " << r2.use_count() << std::endl;  // 3
    }  // r1,r2 gone but cache holds ref
    
    cache.printCacheSize();  // 1
    
    cache.clear();  // clear cache → unload
    
    return 0;
}

Output: 아래 코드는 code를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

load resource: texture1
texture1 in use
r1 ref count: 3
r2 ref count: 3
cache size: 1
cache cleared
unload resource: texture1

5. Common pitfalls

Pitfall 1: Avoiding make_unique / make_shared

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
void func(std::unique_ptr<int> p1, std::unique_ptr<int> p2) {
    // ...
}
int main() {
    // ❌ unsafe: exception safety issue
    // func(std::unique_ptr<int>(new int(1)), std::unique_ptr<int>(new int(2)));
    // evaluation order not guaranteed → possible leak:
    // 1. new int(1)
    // 2. new int(2)
    // 3. unique_ptr ctor (exception can leak 1,2)
    
    // ✅ safe
    func(std::make_unique<int>(1), std::make_unique<int>(2));
    
    // ✅ or
    auto p1 = std::make_unique<int>(1);
    auto p2 = std::make_unique<int>(2);
    func(std::move(p1), std::move(p2));
    
    return 0;
}

Pitfall 2: shared_ptr cycles

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
// ❌ cycle
class Node {
public:
    std::shared_ptr<Node> next;
    std::shared_ptr<Node> prev;  // cycle!
    int value;
    
    Node(int v) : value(v) {
        std::cout << "Node " << value << " created" << std::endl;
    }
    
    ~Node() {
        std::cout << "Node " << value << " destroyed" << std::endl;
    }
};
void testCircular() {
    auto n1 = std::make_shared<Node>(1);
    auto n2 = std::make_shared<Node>(2);
    
    n1->next = n2;
    n2->prev = n1;  // circular ref — dtors never run
    
    std::cout << "n1 ref count: " << n1.use_count() << std::endl;  // 2
    std::cout << "n2 ref count: " << n2.use_count() << std::endl;  // 2
}
// ✅ use weak_ptr
class NodeFixed {
public:
    std::shared_ptr<NodeFixed> next;
    std::weak_ptr<NodeFixed> prev;  // weak_ptr
    int value;
    
    NodeFixed(int v) : value(v) {
        std::cout << "NodeFixed " << value << " created" << std::endl;
    }
    
    ~NodeFixed() {
        std::cout << "NodeFixed " << value << " destroyed" << std::endl;
    }
};
void testFixed() {
    auto n1 = std::make_shared<NodeFixed>(1);
    auto n2 = std::make_shared<NodeFixed>(2);
    
    n1->next = n2;
    n2->prev = n1;  // weak_ptr does not bump strong count
    
    std::cout << "n1 ref count: " << n1.use_count() << std::endl;  // 1
    std::cout << "n2 ref count: " << n2.use_count() << std::endl;  // 2
}
int main() {
    std::cout << "=== circular ref test ===" << std::endl;
    testCircular();
    std::cout << "end function (dtors NOT called!)" << std::endl;
    
    std::cout << "\n=== weak_ptr test ===" << std::endl;
    testFixed();
    std::cout << "end function (dtors called)" << std::endl;
    
    return 0;
}

Output: 다음은 code를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

=== circular ref test ===
Node 1 created
Node 2 created
n1 ref count: 2
n2 ref count: 2
end function (dtors NOT called!)
=== weak_ptr test ===
NodeFixed 1 created
NodeFixed 2 created
n1 ref count: 1
n2 ref count: 2
NodeFixed 2 destroyed
NodeFixed 1 destroyed
end function (dtors called)

Pitfall 3: Passing unique_ptr to functions

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <iostream>
// Option 1: transfer ownership
void takeOwnership(std::unique_ptr<int> ptr) {
    std::cout << "ownership transfer: " << *ptr << std::endl;
}
// Option 2: pass by const& (keep ownership)
void borrow(const std::unique_ptr<int>& ptr) {
    std::cout << "borrow: " << *ptr << std::endl;
}
// Option 3: raw pointer (non-owning)
void observe(int* ptr) {
    if (ptr) {
        std::cout << "observe: " << *ptr << std::endl;
    }
}
int main() {
    auto ptr = std::make_unique<int>(10);
    
    // ❌ compile error
    // takeOwnership(ptr);  // no copy
    
    // ✅ transfer ownership
    // takeOwnership(std::move(ptr));  // ptr becomes nullptr
    
    // ✅ pass by const&
    borrow(ptr);  // ptr still valid
    
    // ✅ raw .get()
    observe(ptr.get());  // ptr still valid
    
    std::cout << "ptr valid: " << (ptr ? "yes" : "no") << std::endl;
    
    return 0;
}

Output:

borrow: 10
observe: 10
ptr valid: yes

6. Example: resource manager

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <memory>
#include <vector>
#include <iostream>
#include <string>
class ResourceManager {
private:
    std::vector<std::unique_ptr<std::string>> resources_;
    
public:
    // add resource
    void add(std::unique_ptr<std::string> resource) {
        resources_.push_back(std::move(resource));
    }
    
    // create and add
    void create(const std::string& value) {
        resources_.push_back(std::make_unique<std::string>(value));
    }
    
    // take (move out)
    std::unique_ptr<std::string> take(size_t index) {
        if (index >= resources_.size()) return nullptr;
        
        auto resource = std::move(resources_[index]);
        resources_.erase(resources_.begin() + index);
        return resource;
    }
    
    // count
    size_t count() const {
        return resources_.size();
    }
    
    // print
    void print() const {
        std::cout << "Resources (" << resources_.size() << "):" << std::endl;
        for (size_t i = 0; i < resources_.size(); ++i) {
            if (resources_[i]) {
                std::cout << "  [" << i << "]: " << *resources_[i] << std::endl;
            } else {
                std::cout << "  [" << i << "]: (moved)" << std::endl;
            }
        }
    }
};
int main() {
    ResourceManager mgr;
    
    // add resource
    mgr.add(std::make_unique<std::string>("Resource 1"));
    mgr.create("Resource 2");
    mgr.create("Resource 3");
    
    std::cout << "initial state:" << std::endl;
    mgr.print();
    
    // take resource
    auto r = mgr.take(1);
    std::cout << "\ntook resource: " << *r << std::endl;
    
    std::cout << "\nremaining:" << std::endl;
    mgr.print();
    
    return 0;
}

Output: 아래 코드는 code를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

initial state:
Resources (3):
  [0]: Resource 1
  [1]: Resource 2
  [2]: Resource 3
took resource: Resource 2
remaining:
Resources (2):
  [0]: Resource 1
  [1]: Resource 3

Summary

Key takeaways

  1. unique_ptr: exclusive; no copy; movable
  2. shared_ptr: shared ownership; ref counting
  3. weak_ptr: break cycles; no strong count bump
  4. make_unique/make_shared: exception safety; performance
  5. RAII: automatic cleanup

Smart pointer comparison

Featureunique_ptrshared_ptrweak_ptr
Ownershipexclusivesharednone
Copynoyesyes
Moveyesyesyes
Overheadnoneref countnone
Usedefaultsharingcycles
Arraysyes (T[])limited-

Practical tips

Selection guide:

  • Default: unique_ptr
  • Sharing: shared_ptr
  • Cycles: weak_ptr
  • Arrays: unique_ptr<T[]> or vector Performance:
  • unique_ptr: same cost as raw pointer
  • shared_ptr: small refcount overhead
  • make_shared: often one allocation Caveats:
  • Prefer make_unique / make_shared
  • Watch for cycles
  • Do not use moved-from objects
  • Avoid dangling pointers

Next steps


More articles connected to this topic.

Practical tips

Tips you can apply at work.

Debugging

  • Check compiler warnings first
  • Reproduce with a minimal test

Performance

  • Do not optimize without profiling
  • Define measurable goals first

Code review

  • Anticipate typical review feedback
  • Follow team conventions

Practical checklist

Use this when applying these ideas in production.

Before you code

  • Is this the best fix for the problem?
  • Can teammates maintain this?
  • Meets performance requirements?

While coding

  • All warnings fixed?
  • Edge cases covered?
  • Error handling OK?

At review

  • Intent clear?
  • Tests sufficient?
  • Documented? Use this checklist to reduce mistakes and improve quality.

C++, smart pointers, unique_ptr, shared_ptr, memory management — searches like these should help you find this article.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3