13.9 Overloading the subscript operator

주홍영·2022년 3월 18일
0

Learncpp.com

목록 보기
152/199

https://www.learncpp.com/cpp-tutorial/overloading-the-subscript-operator/

array를 다룰 때면 우리는 subscript operator []를 이용해 특정 element를 사용하곤 한다
클래서에서 operator[]를 사용하기 위해서 어떻게 해야하는지 살펴보자

Overloading 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;

Why operator[] returns a reference

생각해보면 [] operator를 통해 접근한 value를 l-value로 사용할 수 있기 때문에
ref로 불러오지 않으면 오류가 난다 (생각해보라)
참고로 코딩할 때 int&이 아닌 int로 return 값을 설정한다면 compier가 에러를 뱉는다

Dealing with const objects

만약 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 checking

만약 다음과 같은 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할 수 있도록 조치를 취할 수 있다

The function parameter does not need to be an integer

그리고 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도 구현할 수 있다

profile
청룡동거주민

0개의 댓글