[C++] 스마트 포인터

2024. 6. 9. 17:47·C++/Basic

auto_ptr

#include <memory>

auto_ptr<double> ap(new double);
*ap = 25.5;

- memory헤더 파일을 소스코드에 포함해야한다.

- 메모리가 해제될 때 ap를 해제하고 ap의 파괴자가 동적메모리를 해제한다.

- new로 생성한 단일 객체에 대해서만 메모리의 해제를 보장한다.

- 동일한 메모리 위치를 가리키는 객체를 2개 이상 생성하지 않아야 한다는 점입니다.

- C++11이 지원되는 환경이라면 auto_ptr을 완전히 대체하는 unique_ptr을 사용하면 됩니다.

 

auto_ptr<double> ap(new double);
auto_ptr<double> ap2;
*ap = 25.5;
ap2 = ap;

cout << *ap;

- 다음과 같을 때 ap는 ap2에 소유권을 넘기게된다. 더 안전하다고 할 수 있다.

 

unique_ptr

unique_ptr<double> ap(new double);
unique_ptr<double> ap2;
*ap = 25.5;
ap2 = ap;	//애초에 컴파일에러

cout << *ap;

unique_ptr<double[]> ap3(new double(5));
ap3[0] = 2;

unique_ptr<MyClass> ap4 = make_unique<MyClass>();

- unique_ptr은 단일 소유권을 가진 스마트 포인터로, 소유권을 가진 유일한 스마트포인터가 소멸될 때 자원을 해제합니다.

- 복사는 허용하지 않는다.

- 이동은 가능하다.

- 널이 아닐 때에 소멸시에 자신이 가리키는 자원을 파괴한다.

- 다른 스마트포인터와는 다른 점으로 array로도 사용할 수 있다.

 

unique_ptr<string> demo(const char * s)
{
    unique_ptr,string> temp(new string(s));
    return temp;
}


unique_ptr<string> ps;
ps = demo("Uniquely special");

- 다음과같이 함수를 통해 임시 unique_ptr을 리턴하면 ps는 unique_ptr이 리턴한 객체의 소유권을 얻는다.

- 이렇게 되면 소유권 문제를 해결할 수 있다.

- 유효하지 않은 값에 접근할 가능성이 없어진다.

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() {
        std::cout << "MyClass created" << std::endl;
    }
    ~MyClass() {
        std::cout << "MyClass destroyed" << std::endl;
    }
};

int main() {
    std::unique_ptr<MyClass> uniquePtr = std::make_unique<MyClass>();

    // unique_ptr을 shared_ptr로 이동
    std::shared_ptr<MyClass> sharedPtr = std::move(uniquePtr);

    if (!uniquePtr) {
        std::cout << "uniquePtr is now empty" << std::endl;
    }

    if (sharedPtr) {
        std::cout << "sharedPtr now owns the MyClass instance" << std::endl;
    }

    return 0;
}

 

- move()를 사용하여 shared_ptr에도 대입가능하다.

 

shared_ptr

shared_ptr<double> ap(new double);
shared_ptr<double> ap2;
*ap = 25.5;
ap2 = ap;

cout << *ap;

 

- shared_ptr는 참조를 하게 될 경우 참조카운트를 추가한다. 처음 ap에서 1, ap2에서 같은 객체를 가르킬 때 2로 올라간다.

- reference counting(참조 카운트) 방식으로 객체의 소유권을 공유하게 되며 이 카운트가 0이 되면 객체가 해제됩니다.

- shared_ptr의 객체는 복사가 가능합니다.

- 생포인터도 해당 shared_ptr를 가르킬 수 있지만 shared_ptr이 모두 해제되어 객체가 소멸됐다면 생포인터는 더 이상 nullptr이나 정확한 주소를 가르키고 있지 않고 잘못된 주소를 가르킵니다. 이 경우를 댕글링포인터라고 합니다.

- shared_ptr를 가진 객체가 서로 상호 참조하고 있다면 순환참조를 하게 되어서 카운트가 1이하로 떨어지지않아 삭제되는 문제가 있습니다. 해당 문제를 해결하기 위해서 weak_ptr를 사용합니다.

 

 

weak_ptr

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass(int value) : value(value) {
        std::cout << "MyClass created with value: " << value << std::endl;
    }
    ~MyClass() {
        std::cout << "MyClass destroyed" << std::endl;
    }
    int value;
};

int main() {
    std::shared_ptr<MyClass> sharedPtr = std::make_shared<MyClass>(42);
    std::weak_ptr<MyClass> weakPtr = sharedPtr;

    // Before shared_ptr is reset
    if (auto lockedPtr = weakPtr.lock()) {
        std::cout << "Locked value: " << lockedPtr->value << std::endl;
    } else {
        std::cout << "The object has been destroyed" << std::endl;
    }

    sharedPtr.reset(); // Destroy the shared pointer

    // After shared_ptr is reset
    if (auto lockedPtr = weakPtr.lock()) {
        std::cout << "Locked value: " << lockedPtr->value << std::endl;
    } else {
        std::cout << "The object has been destroyed" << std::endl;
    }

    return 0;
}

 

weak_ptr : shared_ptr과 함께 사용되어 순환 참조를 방지하고 메모리 누수를 방지하기 위해 사용되는 스마트 포인터입니다.

- shared_ptr의 약한 참조를 제공하므로 shared_ptr의 참조 카운트를 증가시키지 않습니다.

- weak_ptr은 shared_ptr으로 참조되는 객체의 유효성을 검사하고, 객체에 접근할 때 **std::lock()**을 사용하여 안전하게 참조합니다. (참조된 주소가 lock())

- weak_ptr이 참조하고 있는 메모리가 해제되었을 때 해당 주소는 잘못된 주소를 가르키지만 lock()을 통해서 안전하게 shared_ptr을 가르키고 있는지 아니면 잘못되거난 빈주소라면 nullptr을 가르키도록 되어 있습니다.

 

 

 

도움사이트 : https://psychoria.tistory.com/42

 

 

 

 

저작자표시 (새창열림)

'C++ > Basic' 카테고리의 다른 글

[C++] 가상함수에 대해  (0) 2024.05.26
함수 오버로딩  (0) 2021.09.17
vector와 list의 차이점  (0) 2021.09.16
[C++] new와 malloc의 차이  (0) 2021.09.15
[C++] 가변인자 템플릿  (0) 2021.08.25
'C++/Basic' 카테고리의 다른 글
  • [C++] 가상함수에 대해
  • 함수 오버로딩
  • vector와 list의 차이점
  • [C++] new와 malloc의 차이
chanheess
chanheess
'왜' 그렇게 했는가?에 대한 생각으로 공부 및 작업의 저장관리
  • chanheess
    왜 그렇게 생각했는가?
    chanheess
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Backend Programming
      • Game Programming
        • Unreal
        • DirectX
      • C++
        • Memo
        • Basic
        • Effective Modern
      • Algorithm
        • Memo
        • Baekjoon
        • Programmers
        • HackerRank, LeetCode
      • Data Structure
      • Design Pattern
      • Etc
        • Memo
        • Daily Log
        • Book
  • 최근 글

  • 최근 댓글

  • 태그

    티스토리챌린지
    백준
    dfs
    SpringSecurity
    c++ 기초 플러스
    dp
    알고리즘
    JWT
    spring
    Java
    프로그래머스
    JPA
    오블완
    위클리 챌린지
  • hELLO· Designed By정상우.v4.10.0
chanheess
[C++] 스마트 포인터
상단으로

티스토리툴바