C++ STL 에서 제공하는 클래스 템플릿으로, 포인터를 객체처럼 관리하면서 메모리 관리를 자동화 함.

개발자가 직접 동적 메모리를 delete 하지 않아도 memory leak을 방지할 수 있음.

smart pointer는 RAII (Resource Acquisition Is Initalization) 원칙을 따른다. 즉, 스마트 포인터 객체의 생명 주기가 끝날 때 (스코프를 벗어날 때), 내부에서 관리하던 동적 메모리를 자동으로 해제함.

스마트 포인터의 종류

  1. std::unique_ptr
  2. std::shared_ptr
  3. std::weak_ptr

예제

  1. std::unique_ptr
#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> ptr1 = std::make_unique<int>(10); // 동적 메모리 관리
    std::cout << "Value: " << *ptr1 << std::endl;

    // std::unique_ptr은 복사 불가능
    // std::unique_ptr<int> ptr2 = ptr1; // 컴파일 오류

    // 소유권 이전 (std::move)
    std::unique_ptr<int> ptr2 = std::move(ptr1);
    if (!ptr1) {
        std::cout << "ptr1 is null after move." << std::endl;
    }
    std::cout << "Value from ptr2: " << *ptr2 << std::endl;

    return 0;
}

출력
Value: 10
ptr1 is null after move.
Value from ptr2: 10
  1. std::shared_ptr
#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> ptr1 = std::make_shared<int>(20); // 동적 메모리 관리
    std::cout << "Value: " << *ptr1 << ", Use count: " << ptr1.use_count() << std::endl;

    std::shared_ptr<int> ptr2 = ptr1; // 공유 소유권
    std::cout << "After sharing, Use count: " << ptr1.use_count() << std::endl;

    ptr2.reset(); // ptr2 소유권 포기
    std::cout << "After reset, Use count: " << ptr1.use_count() << std::endl;

    return 0;
}

출력
Value: 20, Use count: 1
After sharing, Use count: 2
After reset, Use count: 1
  1. std::weak_ptr
#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> sharedPtr = std::make_shared<int>(30);
    std::weak_ptr<int> weakPtr = sharedPtr; // 약한 참조

    std::cout << "Shared use count: " << sharedPtr.use_count() << std::endl;

    if (auto sp = weakPtr.lock()) { // 객체가 존재하면 shared_ptr로 변환
        std::cout << "Value: " << *sp << std::endl;
    }

    sharedPtr.reset(); // shared_ptr가 소유권 포기
    if (weakPtr.expired()) {
        std::cout << "The object has been destroyed." << std::endl;
    }

    return 0;
}