스마트 포인터

JeongChaeJin·2021년 2월 23일
0

cpp_basic

목록 보기
6/6

스마트 포인터

  • 동적 생성된 객체를 가리키는 포인터 자료형을 흉내내어 만든 클래스
    • ->와, * 연산자를 오버로딩하여 포인터와 같은 역할을 수행
    • 동적 생성된 객체를 자동으로 해제하는 기능 제공
    • 다양한 타입을 지원하기 위해 클래스 템플릿으로 정의
  • shared_ptr, unique_ptr, weak_ptr, etc in C++11
  • Ptr in OpenCV
#include <iostream>
#include <memory>

using namepsace std;

class Rect {
public:
    Rect() { cout << "Rect constructor!" << endl; }
    ~Rect() { cout << "Rect destructor!" << endl; }
    void draw() { cout << "Rect drawn!" << endl; }
};

class Ptr {
	Rect* obj;
public:
    Ptr(Rect* p = 0) : obj(p) { cout << "Ptr constructor!" << endl; }
    ~Ptr() {
    	cout << "Ptr destructor!" << endl;
        if (obj) delete obj; // obj가 null이 아니면 delete
    }
    Rect* opreator ->() { return obj; }
};

int main()
{
    Rect rc;
    rc.draw(); // 생성자 -> draw() -> 소멸자 순으로 실행됨.
    
    Rect* pRect = new Rect(); // 동적 생성
    pRect -> draw(); // 생성자 -> draw() 순으로 실행
    // 소멸자가 실행되지 않아 메모리 상에서 문제가 발생할 수 있다.
    
    Ptr rc = new Rect();
    // 동적할당된 객체의 포인터 주소가 rc로 넘어가면서 Ptr 생성자 실행됨.
    rc->draw();
    // Rect 생성자-> Ptr 생성자 -> Rect draw 함수 -> Ptr 소멸자 -> Rect 소멸자
    // new를 했지만 소멸자가 호출되었다.
    
    
    return 0;
}
  • Ptr 처럼 typname이 정해져있는게 아니라 템플릿 형태로 받으면 더 유용할 것이다.
...

template<typename T> class Ptr {
    T* obj;
    public:
    	... // Ptr class와 typename 만 다른 생성자 소멸자 동일
}

int main()
{
	...
    Ptr<Rect> rc = new Rect();
	
    return 0;
}
  • Ptr<\Rect> rc2 = rc; 같이 복사하면 메모리를 두번 해제하면서 오류가 발생된다. 위 처럼 만들려면 예외 처리를 굉장히 잘해야됨.. 그래서 C++ 에서 shared_ptr 사용 !
...

int main()
{
	...
    
    shared_ptr<Rect> rc2 = new Rect();
    
    rc2->draw(); // 정상동작
    
    return 0
profile
OnePunchLotto

0개의 댓글