[C++] 스마트 포인터, operator*(), operator->() 연산자 오버로딩

2019. 7. 30. 00:06 기타/C++

[C++] 스마트 포인터, operator*(), operator->() 연산자 오버로딩


스마트 포인터는 일반 포인터의 기능에 몇 가지 유용한 기능을 추가한 포인터처럼 동작하는 객체이다.


일반 포인터를 사용하면 new 연산 후 delete 연산을 호출하지 않으면 메모리 누수가 발생하여 프로그램에 심각한 문제가 된다.


또한, 사용 중에 함수가 종료하거나 예외 등이 발생하면 동적으로 할당한 메모리를 해제하지 못하는 문제가 발생한다.

이런 문제들을 스마트 포인터를 사용하여 쉽게 해결할 수 있다.



* 간단한 스마트 포인터 예제


class PointPtr{
    
    Point* ptr;

public:
    PointPtr(Point* p)
        :ptr(p){}
    
    ~PointPtr(){
        delete ptr;
    }
};


위와 같이 Point 클래스에 대한 스마트 포인터를 만들었다.


Point 객체를 메모리에 할당할 때 PointPtr 의 생성자에 넣어 생성하면, PointPtr 이 소멸하면서 소멸자를 호출하고 Point 객체를 delete 로 해제한다.

스마트 포인터를 사용하면, delete 문을 작성해줄 필요가 없으며, 예외 발생에도 안전하다.


하지만, 이 스마트 포인터를 사용하여 Point 객체에 접근하고 함수를 호출하려면, * 와 -> 연산자를 재정의 해줘야 한다.

현재 상태로는 Point 객체에 접근할 수 없다.


operator*() : * 연산자 오버라이딩

operator->() : -> 연산자 오버라이딩


아래의 예제와 같이 operator 를 오버라이딩 하고 스마트 포인터를 사용하면 된다.



#include <iostream>
using namespace std;

class Point{
    int x;
    int y;

public:
    Point(int _x = 0, int _y = 0)
        :x(_x), y(_y){}
    void Print() const{
        cout << x << ',' << y << endl;
    }
};

class PointPtr{
    
    Point* ptr;

public:
    PointPtr(Point* p)
        :ptr(p){}
    
    ~PointPtr(){
        delete ptr;
    }

    Point* operator->() const{
        return ptr;
    }
    Point& operator*() const{
        return *ptr;
    }
};

int main(){

    Point* p1 = new Point(2, 3);
    p1->Print();
    (*p1).Print();

    delete p1;
    
    cout << endl;

    PointPtr p2 = new Point(5, 5);
    p2->Print();
    (*p2).Print();

    return 0;
}


결과


2,3,

2,3


5,5

5,5



그냥 Point 객체를 메모리에 생성하는 것과 스마트 포인터를 사용하는 것의 차이를 보여준다.

같은 결과가 나온다.



출처: https://hyeonstorage.tistory.com/312?category=601868 [개발이 하고 싶어요]