티스토리 뷰

배열의 인덱스 연산자 오버로딩 [ ] 

- 배열은 저장소의 일종이고, 저장소에 저장된 데이터는 유일성이 보장되어야 하기에, 대부분의 경우 저장소의 복사는 하지 않는다. 따라서 몸체가 빈 상태인 복사 생성자와 대입 연산자를 private으로 선언해 복사와 대입을 막는다.

 

- 배열의 인덱스 연산자 오버로딩은 다음과 같이 배열의 값을 단순 출력하는 함수는 const로, 값을 대입 및 수정할 때는 const가 아닌 함수로 두개의 함수로 정의한다. (오버로딩) 

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

class BoundCheckIntArray
{
private:
    int *arr;
    int arrlen;
    // 복사, 대입을 막기 위해 복사 생성자와 대입 연산자를 private 선언
    BoundCheckIntArray(const BoundCheckIntArray &arr) {}
    BoundCheckIntArray& operator= (const BoundCheckIntArray &arr) {}
public:
    BoundCheckIntArray(int len) : arrlen(len) { arr = new int[len]; }
    // const 없는 operator[]
    int& operator[] (int idx)
    {
        if(idx < 0 || idx >= arrlen)
        {
            cout << "Array idx out of bound exception" << endl;
            exit(1);
        }
        return arr[idx];
    }
    // const로 오버라이딩된 operator[]
    int operator[] (int idx) const
    {
        if(idx < 0 || idx >= arrlen)
        {
            cout << "Array idx out of bound exception" << endl;
            exit(1);
        }
        return arr[idx];
    }
    int GetArrLen() const { return arrlen; }
    ~BoundCheckIntArray() { delete []arr; }
};

void ShowAllData(const BoundCheckIntArray& ref)
{
    int len = ref.GetArrLen();
    for(int i = 0; i < len; i++)
        // ref.operator[](i)이고 매개변수를 const 형으로 받았으므로
        // const 오버라이딩되어있는 operator[] 실행됨
        cout << ref[i] << endl;
}

int main()
{
    BoundCheckIntArray arr(5);
    for(int i = 0; i <5; i++)
        // const 아닌 arr을 이용한 연산이므로 const가 아닌 operator[] 실행
        arr[i] = (i + 1) * 11;
    ShowAllData(arr);
}

 


문제 11-2 [C++ 기반의 데이터 입출력] 

문제 1

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


class Point
{
private:
    int xpos, ypos;
public:
    Point(int x = 0, int y = 0) : xpos(x), ypos(y) {}
    friend ostream& operator<< (ostream& os, const Point& pos);
    friend ostream& operator<< (ostream &os, const Point* pos);
};

// Point&를 받아서 좌표 출력 
ostream& operator<< (ostream& os, const Point& pos)
{
    os << '[' << pos.xpos << ", " << pos.ypos << ']' << endl;
    return os;
}
// Point* 받아서 포인터 타고가서 좌표 출력 
ostream& operator<< (ostream &os, const Point* pos)
{
    os << '[' << pos->xpos << ", " << pos->ypos << ']' << endl;
    return os;
}

typedef Point * POINT_PTR;

class BoundCheckPointPtrArray
{
private:
    POINT_PTR * arr; // double pointer
    int arrlen;
    // 복사 생성자, 대입 연산자 오버라이딩 금지
    BoundCheckPointPtrArray(const BoundCheckPointPtrArray& arr) {}
    BoundCheckPointPtrArray& operator= (const BoundCheckPointPtrArray& arr) {}
public:
    BoundCheckPointPtrArray(int len) : arrlen(len)
    {
        arr = new POINT_PTR[len]; // 저장의 대상이 Point 객체의 주소값
    }
    POINT_PTR& operator[] (int idx)
    {
        if(idx < 0 || idx >= arrlen)
        {
            cout << "Array idx out of bound exception" <<endl;
            exit(1);
        }
        return arr[idx];
    }
    POINT_PTR operator[] (int idx) const
    {
        if(idx < 0 || idx >= arrlen)
        {
            cout << "Array idx out of bound exception" <<endl;
            exit(1);
        }
        return arr[idx];
    }
    int GetArrLen() const { return arrlen; }
    ~BoundCheckPointPtrArray() {delete []arr; }
};



int main()
{
    BoundCheckPointPtrArray arr(3);
    arr[0] = new Point(3,4);
    arr[1] = new Point(5,6);
    arr[2] = new Point(7,8);

    for(int i = 0; i < arr.GetArrLen(); i++)
        cout << *(arr[i]);
    cout << endl;

    for(int i = 0; i < arr.GetArrLen(); i++)
        cout << arr[i];
    cout << endl;

    delete arr[0];
    delete arr[1];
    delete arr[2];
}

 

아래와 같이 작성한 코드에서

for(int i = 0; i < arr.GetArrLen(); i++)
    cout << *(arr[i]);
cout << endl;

아래와 같은 출력을 얻고 싶다

arr의 자료형은 BoundCheckPointPtrArray이고, 각 인덱스에는 Point *, 즉 Point 객체의 주소값이 저장된다. 

arr[i] 에는 Point의 포인터 정보가 있고 cout <<  *(arr[i]) 이므로 operator<< 에 전달되는 파라미터의 자료형은 ostream& 그리고 Point의 레퍼런스 정보인 Point& 이다. 

// Point&를 받아서 좌표 출력
ostream& operator<< (ostream& os, const Point& pos)
{
    os << '[' << pos.xpos << ", " << pos.ypos << ']' << endl;
    return os;
}

 

이번에는 아래와 같이 작성한 코드에서 위의 출력과 같은 결과를 얻고 싶다 

for(int i = 0; i < arr.GetArrLen(); i++)
    cout << arr[i];
cout << endl;

arr[i]에는 Point 객체의 주소값이 저장되어 있으므로 넘겨지는 파라미터의 자료형은 Point* 이다. 

 

ostream& operator<< (ostream &os, const Point* pos)
{
    os << '[' << pos->xpos << ", " << pos->ypos << ']' << endl;
    return os;
}

 

 

문제 2

#include <iostream>
using namespace std;


class BoundCheckIntArray
{
private:
    int *arr;
    int arrlen;
    // 복사, 대입을 막기 위해 복사 생성자와 대입 연산자를 private 선언
    BoundCheckIntArray(const BoundCheckIntArray &arr) {}
    BoundCheckIntArray& operator= (const BoundCheckIntArray &arr) {}
public:
    BoundCheckIntArray(int len) : arrlen(len) { arr = new int[len]; }
    // const 없는 operator[]
    int& operator[] (int idx)
    {
        if(idx < 0 || idx >= arrlen)
        {
            cout << "Array idx out of bound exception" << endl;
            exit(1);
        }
        return arr[idx];
    }
    // const로 오버라이딩된 operator[]
    int operator[] (int idx) const
    {
        if(idx < 0 || idx >= arrlen)
        {
            cout << "Array idx out of bound exception" << endl;
            exit(1);
        }
        return arr[idx];
    }
    int GetArrLen() const { return arrlen; }
    ~BoundCheckIntArray() { delete []arr; }
};

class BoundCheck2DIntArray
{
private:
    BoundCheckIntArray **arr;
    int arrlen;
    BoundCheck2DIntArray(const BoundCheck2DIntArray& arr) {}
    BoundCheck2DIntArray& operator= (const BoundCheck2DIntArray& arr) {}

public:
    BoundCheck2DIntArray(int c, int r) : arrlen(c)
    {
        arr = new BoundCheckIntArray*[c];
        for(int i = 0; i < c; i++)
            arr[i] = new BoundCheckIntArray(r);
    }
    BoundCheckIntArray& operator[] (int idx)
    {
        if(idx < 0 || idx >= arrlen)
        {
            cout << "Array idx out of bound exception" << endl;
            exit(1);
        }
        return *(arr[idx]);
    }
    ~BoundCheck2DIntArray()
    {
        for(int i = 0; i < arrlen; i++)
            delete arr[i];
        delete []arr;
    }
};

int main()
{
    BoundCheck2DIntArray arr2d(3, 4);

    for(int n = 0; n < 3; n++)
        for(int m = 0; m < 4; m++)
            arr2d[n][m] = n + m;

    for(int n = 0; n < 3; n++)
    {
        for(int m = 0; m < 4; m++)
        {
            cout << arr2d[n][m] << ' ';
        } cout << endl;
    }
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/02   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
글 보관함