https://www.learncpp.com/cpp-tutorial/overloading-the-subscript-operator/
array를 다룰 때면 우리는 subscript operator []를 이용해 특정 element를 사용하곤 한다
클래서에서 operator[]를 사용하기 위해서 어떻게 해야하는지 살펴보자
subscript operator는 member function으로 구현되어야 한다
우리는 []로 원본에 접근할 수 있어야 하므로 reference로 return을 설정한다
class IntList
{
private:
int m_list[10]{};
public:
int& operator[] (int index);
};
int& IntList::operator[] (int index)
{
return m_list[index];
}
위와 같이 클래스를 설정하고 member function을 정의하면 다음과 같이 사용할 수 있다
IntList list{};
list[2] = 3; // set a value
std::cout << list[2] << '\n'; // get a value
return 0;
생각해보면 [] operator를 통해 접근한 value를 l-value로 사용할 수 있기 때문에
ref로 불러오지 않으면 오류가 난다 (생각해보라)
참고로 코딩할 때 int&이 아닌 int로 return 값을 설정한다면 compier가 에러를 뱉는다
만약 const object에서 []operator를 사용한 경우 어떻게 해야되나?
c++에서는 const 버젼과 non-const 버젼을 분리해서 정의할 수 있다
#include <iostream>
class IntList
{
private:
int m_list[10]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // give this class some initial state for this example
public:
int& operator[] (int index);
int operator[] (int index) const; // could also return const int& if returning a non-fundamental type
};
int& IntList::operator[] (int index) // for non-const objects: can be used for assignment
{
return m_list[index];
}
int IntList::operator[] (int index) const // for const objects: can only be used for access
{
return m_list[index];
}
int main()
{
IntList list{};
list[2] = 3; // okay: calls non-const version of operator[]
std::cout << list[2] << '\n';
const IntList clist{};
clist[2] = 3; // compile error: calls const version of operator[], which returns a const reference. Cannot assign to this.
std::cout << clist[2] << '\n';
return 0;
}
만약 다음과 같은 error 상황은 어떻게 할까?
int list[5]{};
list[7] = 3; // index 7 is out of bounds!
우리는 멤버 변수의 사이즈를 알고 있으므로 error checking을 할 수 있다
#include <cassert> // for assert()
#include <iterator> // for std::size()
class IntList
{
private:
int m_list[10]{};
public:
int& operator[] (int index);
};
int& IntList::operator[] (int index)
{
assert(index >= 0 && index < std::size(m_list));
return m_list[index];
}
assert() function을 이용해 조건이 참이 아니면 error message와 함께 terminate할 수 있도록 조치를 취할 수 있다
그리고 function의 parameter는 꼭 integer일 필요는 없다
#include <iostream>
#include <string>
class Stupid
{
private:
public:
void operator[] (const std::string& index);
};
// It doesn't make sense to overload operator[] to print something
// but it is the easiest way to show that the function parameter can be a non-integer
void Stupid::operator[] (const std::string& index)
{
std::cout << index;
}
int main()
{
Stupid stupid{};
stupid["Hello, world!"];
return 0;
}
위와 같이 string을 index로 받아서 출력하는 operator overloading도 구현할 수 있다