unisque_ptr : 포인터가 가리키고있는 데이터의 소유권이 한 곳에만 속할 경우 쓰는 스마트 포인터

#include <iostream>
#include <memory>
#include "Resource.h"

auto doSomething()
{
    return std::unique_ptr<Resource>(new Resource(5));
}

void doSomething2(std::unique_ptr<Resource> & res)
{
    res->setAll(10);
}

using namespace std;

int main()
{
    {
        //Resource *res = new Resource(10000000);
        std::unique_ptr<Resource> res(new Resource(10000000)); // delete이 없지만 스스로 destructor 호출
        //delete res;
    }
    
    return 0;
}
#include <iostream>
#include <memory>
#include "Resource.h"

auto doSomething()
{
    return std::unique_ptr<Resource>(new Resource(5));
}

//void doSomething2(std::unique_ptr<Resource> & res)
//{
//    res->setAll(10);
//	  res->print();  
    //return res
//}

void doSomething2(Resource *res)
{
    res->setAll(100);
    res->print();
    
}



using namespace std;

int main()
{
    {
        std::unique_ptr<int> upi(new int);
        
        auto *ptr = new Resource(5);
        //std::unique_ptr<Resource> res1(ptr);
        std::unique_ptr<Resource> res1(new Resource(5));
        //auto res1 = std::make_unique<Resource>(5);
        //auto res1 = doSomething(); // 초기화 방법
        
        res1->setAll(5);
        res1->print();
        
        std::unique_ptr<Resource> res2;
        
        std::cout << std::boolalpha;
        std::cout << static_cast<bool>(res1) << "\n"; // nullptr이 아님 => True
        std::cout << static_cast<bool>(res2) << "\n"; // res2는 갖고있는게 없으므로 nullptr => False
        
        // res2 = res1; // unique_ptr은 복사가 안된다. 소유권이 유일하기 때문. 
        res2 = std::move(res1);
        
        std::cout << std::boolalpha;
        std::cout << static_cast<bool>(res1) << "\n";
        std::cout << static_cast<bool>(res2) << "\n";
        
        if (res1 != nullptr) res1->print();
        if (res2 != nullptr) res2->print(); // (*res2).print();
    }
    
    return 0;
}

출력

Resource length constructed
5 5 5 5 5
true
false
false
true
5 5 5 5 5
Resource destroyed

다른 예제

#include <iostream>
#include <memory>
#include "Resource.h"

auto doSomething()
{
    return std::unique_ptr<Resource>(new Resource(5));
}

//void doSomething2(std::unique_ptr<Resource> & res)
//{
//    res->setAll(10);
//	  res->print();  
    //return res
//}

void doSomething2(Resource *res)
{
    res->setAll(100);
    res->print();
    
}

using namespace std;

int main()
{
    {
        auto res1 = std::make_unique<Resource>(5);
        res1->setAll(1);
        res1->print();
        
        //doSomething2(res1); // 컴파일이 안된다. res1은 copy가 안되니까 l-value reference로 받으면 안된다. (&일 때)
        doSomething2(std::move(res1)); // 이렇게 하면 res1은 nullptr이 된다.
        // 만약 res1을 다시 사용하고 싶다면 return res를 하면 된다.
        doSomething2(res1.get()); // unique_ptr의 get함수. resource의 포인터를 가져오는 함수. l-value reference처럼 작동.
        
        res1->print();
        
    }
    
    return 0;
}

다른 예제

#include <iostream>
#include <memory>
#include "Resource.h"

auto doSomething()
{
    return std::unique_ptr<Resource>(new Resource(5));
}

//void doSomething2(std::unique_ptr<Resource> & res)
//{
//    res->setAll(10);
//	  res->print();  
    //return res
//}

void doSomething2(Resource *res)
{
    res->setAll(100);
    res->print();
    
}

using namespace std;

int main()
{
    {
        Resource *res = new Resource;
        std::unique_ptr<Resource> res1(res);
        std::unique_ptr<Resource> res2(res); // 이렇게 사용하면 안됨. 소유권은 반드시 하나
        
        delete res; // 두번 지우려고 하니 문제가 생김.
        
    }
    
    return 0;
}