본문 바로가기
Dev Language/Modern C++ (C++11, 14)

C++ 11 : unique_ptr

by 미티치 2020. 8. 8.
#include <tchar.h>
#include <stdio.h>
#include <memory>

struct  BodyMass
{
    int        ID;
    float    Weight;


    BodyMass(int id, float weight) : ID(id), Weight(weight)
    {
        std::cout << "BodyMass is constructed!" << std::endl;
    }
    
    BodyMass(const BodyMass & other) : ID(other.ID), Weight(other.Weight)
    {
        std::cout << "BodyMass is copy constructed!" << std::endl;
        std::cout << "copy constructed >> ID    =" << ID    << std::endl;
        std::cout << "copy constructed >> Weight=" << Weight<< std::endl;
    }
    ~BodyMass()
    {
        std::cout << "BodyMass is destructed!" << std::endl;
    }


public:
    int getID(void)
    {
        return ID;
    }


    float getWeight(void)
    {
        return Weight;
    }
};

auto main() -> int
{
    using namespace std;

    unique_ptr< BodyMass > bodymass1 = unique_ptr< BodyMass >{ new BodyMass(1, 50.2f) };
    unique_ptr< BodyMass > bodymass2 = make_unique< BodyMass >(2, 63.3f);


    cout << "bodymass1 get info =====================" << endl;
    cout << "bodymass1.getID        = " << bodymass1->getID() << endl;
    cout << "bodymass1.getWeight    = " << bodymass1->getWeight() << endl;


    cout << "bodymass2 get info =====================" << endl;
    cout << "bodymass2.getID        = " << bodymass2->getID() << endl;
    cout << "bodymass2.getWeight    = " << bodymass2->getWeight() << endl;


    cout << "\n=======================================" << endl;
    auto bodymass3 = bodymass2;    // 컴파일 에러
    auto bodymass3 = *bodymass2;    // 이건 가능

    return 1;
}

위 소스 테스트해보니 unique_ptr 은 독점 소유권을 제공 ( 가리키는 객체를 독점한다는 의미 ) 하기 때문에, 마지막 빨간 라인은 컴파일 오류가 발생한다.

이때 발생하는 컴파일 오류 내용은 아래와 같은데,

 

밑에 파란 줄 부분을 클릭해서 들어가니까 <memory> 헤더의 이 부분을 가리키고 있다.

 

즉,  unique_ptr 은 복사 생성자를 명시적으로 delete 해놓음으로써 객체에 대한 독점 소유권을 제공하는 것이다.

( -> 책에는 객체를 독점므로 복사생성자와 복사할당자가 없다고 되어 있다. )

 

근데 밑에 auto bodymass3 = *bodymass2 ; 는 성립되는 이유는

bodymass2 는 unique_ptr 객체이지만, *bodymass2는 unique_ptr 객체의 값 이기 때문에

auto bodymass3 = *bodymass2 ; 는 'unique_ptr 객체의 값'을 복사하는 것이므로 가능하다. 또한 결과를 확인하면 복사생성자에서 찍은 cout 내용들이 찍힌다

아래는 결과


std::unique_ptr<BodyMass> GetBodyMass()
{
    return std::make_unique<BodyMass>(1, 165.3f);
}


std::unique_ptr<BodyMass> UpdateBodyMass(std::unique_ptr<BodyMass> bodymass)
{
    bodymass->Weight += 1.0f;
    return bodymass;
}


auto main() -> int
{
    using namespace std;


    auto bodymass = GetBodyMass();
    
    cout << "GetBodyMass bodymass Weight    = " << bodymass->getWeight() << endl;


    bodymass = UpdateBodyMass(bodymass);        // 컴파일 오류 내용 : "삭제된 함수를 참조하려고 합니다. "
    bodymass = UpdateBodyMass(move(bodymass));  // 얘는 가능


    cout << "\n=======================================" << endl;
    cout << "UpdateBodyMass bodymass Weight    = " << bodymass->getWeight() << endl;


    return 1;
}

마찬가지로 얘도 빨간 글씨 부분은 컴파일 에러. 여기서 삭제된 함수는 위의 결과와 동일하게 <memory> 의 2337 라인이었다. 즉, 복사 안된다는 말