(C++) unique_ptr

Posted by : at

Category : Cpp


이렇게 쓰면 좋겠지?

#include <iostream>
#include <memory>
using namespace std;

class cl1
{
public:
	cl1() { cout << "cl1()" << endl; }
	~cl1() { cout << "~cl1()" << endl; } 
    void printCL1() { cout << "Hello This is CL!" << endl; }
};

class parent1
{
public:
	parent1(int num) { cout << "parent1() : " << num << endl; m_num = num; }
	~parent1() { cout << "~parent1() : " << m_num  << endl; }
	void SetCL1(shared_ptr<cl1> _cl1) { m_cl1 = _cl1; }
    void PrintCL1() { m_cl1->printCL1(); }

private:
	shared_ptr<cl1> m_cl1;
    int m_num = -1;
};

int main() {
	// your code goes here
	shared_ptr<cl1> m_cl1 = make_shared<cl1>();

	unique_ptr<parent1> m_pr1 = make_unique<parent1>(1);
	parent1* m_pr2 = new parent1(2);

	m_pr1->SetCL1(m_cl1);
	m_pr2->SetCL1(m_cl1);

    m_pr1->PrintCL1();
    m_pr2->PrintCL1();

	return 0;
}
  • 해당 클래스에서 사용하는 포인터 : unique_ptr
  • 다른 클래스에서 참조해야할 포인터 : shared_ptr
cl1()
parent1() : 1
parent1() : 2
Hello This is CL!
Hello This is CL!
~parent1() : 1

unique_ptr이란?

  • 메모리주소의 참조를 독점할 수 있는 포인터
  • 왜쓰나? 굳이 소멸자를 호출하지 않아도 되는 장점이 있다!
#include <iostream>
#include <memory>

using namespace std;

// Data structure representing a point on the screen
struct point {
    int x;
    int y;
};

int main() {
	// Create a unique_ptr to an point which has initial value {3,6}
	auto p{ make_unique<point>( point{3, 6} ) };
	//unique_ptr<point> p{ new point{3, 6} };          // C++11

	cout << p->x << ", " << p->y << endl;
}
#include <iostream>
#include <memory>

using namespace std;

// Data structure representing a point on the screen
struct point {
    int x;
    int y;
};

unique_ptr<point> create_ptr() { 
    point p{0};                                  // Create point instance
    p.x = 3;                                     // Populate point instance
	p.y = 6;	
    unique_ptr<point> ptr = make_unique<point>(p);     // Create local unique_ptr instance
    return ptr;                                    // The pointer member is transferred
                                                 // from p to the returned instance
}

int main() {
	unique_ptr<point> upp { create_ptr() };

	cout << upp->x << ", " << upp->y << endl;
}
#include <iostream>
#include <memory>
using namespace std;

class Car
{
    int color;
    int speed;
public:
    ~Car() { cout << "~Car()" << endl; }
 
    void Go() { cout << "Car go" << endl; }
};

int main()
{
    shared_ptr<Car> sp1(new Car);
    shared_ptr<Car> sp2 = sp1;      // 참조 계수 2

    unique_ptr<Car> up1(new Car);   // 자원 독점
    unique_ptr<Car> up2 = up1;      // error

그런데 그래도 옮겨야할 때가 발생한다면?? (move이용)

#include <iostream>
#include <memory>
using namespace std;

int main()
{
    unique_ptr<int> up1(new int);

    unique_ptr<int> up2 = move(up1);        // ok.
}

삭제자 선언하기

#include <iostream>
#include <memory>
using namespace std;

struct Deleter
{
    void operator()(int* p) const
    {
        delete p;
    }
}

int main()
{
    unique_ptr<int> up1(new int);

    // 삭제자는 이렇게 선언
    unique_ptr<int, Deleter> up(new int);

    // 이런 삭제자도 가능 - 1
    unique_ptr<int, void(*)(int*)> up(new int, foo);

    // 이런 삭제자도 가능 - 2
    auto f = [](int*p){delete p;}
    unique_ptr<int, decltype(f)> up(new int, f);
}
// 배열도 사용가능 (C++11)
unique_ptr<int[]> up(new int[10]);

shared_ptr <-> unique_ptr 호환성

#include <iostream>
#include <memory>
using namespace std;

int main()
{
    shared_ptr<int> sp(new int);
    unique_ptr<int> up(new int);

    shared_ptr<int> sp1 = up;       // error
    shared_ptr<int> sp2 = move(up); // ok

    unique_ptr<int> up1 = sp;       // error
    unique_ptr<int> up2 = move(sp); // error
}

Example

#include <iostream>
#include <memory>
using namespace std;

class Shape {};
class Rect : public Shape {};
class Circle : public Shape {};

Shape* CreateShape(int type)
{
    Shape* p = nullptr;

    switch(type)
    {
        case 1 : p = new Rect; break;
        case 2 : p = new Circle; break;
    }
    return p;
}

int main()
{
    Shape* p = CreateShape(1);
#include <iostream>
#include <memory>
using namespace std;

class Shape {};
class Rect : public Shape {};
class Circle : public Shape {};

unique_ptr<Shape> CreateShape(int type)
{
    unique_ptr<Shape> p;

    switch(type)
    {
        case 1 : p.reset(new Rect); break;
        case 2 : p.reset(new Circle); break;
    }
    return p;
}

int main()
{
    // unique_ptr<Shape> p = CreateShape(1);
    shared_ptr<Shape> p = CreateShape(1);
    // unique, shared 모두 사용가능
unique_ptr<uint8_t[]> mp_array;

// 선언
mp_array = std::make_unique<uint8_t[]>(48000 * 8);

// uint8_t* 의 호출이 필요할 경우
&mp_array[0];

About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links