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

인덱스 연산자

  • C++에는 인덱스 연산자 오버로딩도 존재한다
  • int 배열의 경우 : int& operator[](int idx)
  • 이를 통해 새로운 클래스를 정의하고 배열의 버퍼를 벗어나는 상황의 예외처리가 가능해짐
    • 예 : arr[-1], arr[-100], 크기 3인 arr에서 arr[3] 등

const 함수를 이용한 오버로딩의 활용

class BoundCheckIntArray{
private:
    int * arr;
    int arrlen;
    BoundCheckIntArray(const BoundCheckIntArray& arr) {}
    BoundCheckIntArray& operator=(const BoundCheckIntArray& arr) {}
public:
    BoundCheckIntArray(int len) : arrlen(len){
        arr = new int[len];
    }
    int& operator[] (int idx){
        if(idx<0 || idx>=arrlen){
            cout<<"Array index 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 idx = 0 ; idx<len ; idx++){
        cout<<ref[idx]<<endl;
    }
}

int main(){
    BoundCheckIntArray arr(5);
    for(int i = 0 ; i < 5 ; i++){
        arr[i] = (i+1)*11;
    }
    ShowAllData(arr);
    return 0;
}
  • 위 코드는 컴파일 에러가 발생한다.
  • 이유는?
    void ShowAllData(const BoundCheckIntArray& ref){
      int len = ref.GetArrLen();
      for(int idx = 0 ; idx<len ; idx++){
          cout<<ref[idx]<<endl;
      }
    }
    • 위 코드에서 인자로 BoundCheckIntArray가 const로 전달되어 수정을 막고 있다.
    • 그러나 operator= 연산자 오버로딩 함수는 const 함수가 아니기 때문에 컴파일 오류를 발생시킴.

    ⚠️ 인자가 const로 들어오면, const함수가 아닌 모든 함수를 사용할 수 없음에 유의

해결방안

  • operator= 연산자 오버로딩 함수를 const인것 하나, 아닌것 하나로 오버로딩한다.
  • 거의 완전히 같은 함수이지만, const가 붙냐 안붙냐의 차이만 있음.
#include <iostream>
#include <cstdlib>
using namespace std;

class BoundCheckIntArray{
private:
    int * arr;
    int arrlen;
    BoundCheckIntArray(const BoundCheckIntArray& arr) {}
    BoundCheckIntArray& operator=(const BoundCheckIntArray& arr) {}
public:
    BoundCheckIntArray(int len) : arrlen(len){
        arr = new int[len];
    }
    /*
     * 수정된 부분 시작------------------------------
     */
    int& operator[] (int idx){
        if(idx<0 || idx>=arrlen){
            cout<<"Array index out of bound exception"<<endl;
            exit(1);
        }
        return arr[idx];
    }
    int& operator[] (int idx) const{
        if(idx<0 || idx>=arrlen){
            cout<<"Array index 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 idx = 0 ; idx<len ; idx++){
        cout<<ref[idx]<<endl;
    }
}

int main(){
    BoundCheckIntArray arr(5);
    for(int i = 0 ; i < 5 ; i++){
        arr[i] = (i+1)*11;
    }
    ShowAllData(arr);
    return 0;
}
  • 이러면 const로 들어온 인자에 대해서도 배열 인덱스 연산자 오버로딩 함수 호출이 가능해진다.