이 게시글은
서울대학교 데이터사이언스대학원
조요한 교수님의
데이터사이언스 응용을 위한 컴퓨팅 강의를
학습을 위해 재구성하였습니다.
operator overloading 2편!
시시시시작..
cout에서 자주 쓰이는
<< operator의 구현을 알아보자
<<는 traditional하게는
오른쪽의 object에 인자로 받은 값을
append 시키는 기능을 한다
또한 tradition하게는
Object 자기 자신을 반환하므로
return값으로는 reference값
input으로는 오른쪽의 object를 받아준다
그냥 현재 벡터에 내부적으로
addElement를 해주는거고
반환값으로는 append한
자기 자신 reference를 반환해준다
그다음 또 하나 주목해야할게
input에 const가 있는걸 확인할 수 있는데
왜 const가 있을까?
literal값을 받기 위해서다
input으로 변수가 아닌
4, 5, "hello"같은 literal값이
들어올 수가 있는데
const를 넣어줘야 이 literal값을
정상적으로 append할 수 있다
이번엔 == operator를 보자
같으면 true, 다르면 false를
반환해야하기때문에
return값은 bool이다
operator==를 해주고
인자로는 SimpleVector를 넣어준다
내부에서 size가 다르면
당연히 두 SimpleVector가 아니므로
false를 반환해준다
그다음 요소 하나하나를 비교하면서
한개라도 다르면 false를
모든 if문에서 통과했으면
true를 반환해준다
이제 < operator를 보자
size를 check해서 더 작으면
true를 반환해주는 연산자이다
따라서 bool을 return으로 받고
SimpleVector를 input으로 받은 뒤
size를 가져와서 비교한 bool값을
반환해준다
bool operator에 대해 알아보자
bool operator는 지금까지의
operator 구현과는 조금 다르다
우선 true가 뭔지 false가 뭐인지부터
미리 정의를 해줘야한다
operator bool()과 같이 선언해주고
const 안에 return값을 반환해준다
위 ppt를 보면
size가 0보다 크면 true를 반환하고있다
이렇게 bool operator를 정의해주면
SimpleVector를 bool로 반환해야하는
상황이 생기면 const 내부 값을 호출하게된다
정확히 컴파일러가 어떤 과정을 거쳐서
bool operator를 수행하는지 보자
main 함수에서
if (vec1) 와 같이 코딩을 했다면
SimpleVector가 bool값으로
반환되어야하는 상황임을 인지하고
bool operator 정의부로 들어간다
그래서 내부 내용을 수행한 뒤
true/false값을 반환하게 된다
혹은 프로그래머가
SimpleVector의 typecasting을
bool로 해도 호출된다
이런 bool operator를 사용해주는 예시로
fileInputStream이 있는데
file의 내용을 가져올 때
while (cin >> value)와 같은 방식으로
가져오는걸 본 적이 있을 것이다
저 구문을 통해서 어떻게
value값을 읽어오는지 생각해보자
위에서 >> operator의 구현을 살펴봤는데
>> operator는 반환값으로
object 자기 자신을 반환한다
따라서 cin >> value는
반환값으로 value가 append된
자기 자신을 반환한다
cin class의 bool operator는
지금까지 발생한 error가 있으면 false를
error가 없으면 true를 반환하도록 구현되어있는데
while (cin >> value)를 통해서
value를 append하고
conditional statement를 체크하기위해
bool operator 정의를 찾고
에러가 없으면 true를 반환하니까
계속해서 다음 value를 cin class안에
append하게 되는 것이다
그리고 value의 값이 이제 끝나거나
어떤 에러가 발생했다면
bool operator에서 false를 반환하고
while문을 탈출하게된다
마지막으로 range-based for loop에 대해 알아보자
for (auto element : vec) {
cout << elemlent << " ";
}
이렇게 쓰는걸 range-based for loop이라고 하는데
정확하게 말하면 operator overloading은 아니지만
유용하기 때문에 어떻게 작동하게하는지 알아보자
우선 이걸 사용할 수 있게 하려면
begin()과 end()를 정의해줘야한다
begin()은 첫 번째 포인터를 반환하고
end()는 마지막보다 1(size) 더간 포인터를 반환한다
이렇게 begin()과 end()가 정의되어있으면
range-based for loop를 사용할 수 있다
그럼 이제 이 begin()과 end()를 이용해서
compiler는 어떻게 이걸 구현하는지 살펴보자
위 ppt 코드의 예시를 통해 알아보겠다
우선 loop가 사용되면
vec의 begin()을 호출한다
그럼 첫 번째 포인터가 반환될텐데
이를 dereference한 걸 element라는 변수에 넣어준다
그렇게 iteration을 돌 때 마다
포인터를 ++ 해준다
iteration을 돌면서
++해준 포인터가 end()와
같은지 아닌지를 체크하다가
end()와 동일하다면
for문을 탈출하도록 구현되어있다
Non-Member Functions
지금까지는 모든 operator들을
SimpleVector라는 class 내부의
method로 정의를 했다
그런데 class 밖에서
global scope로
non member function을
정의할 수 있는데
유용한 방법이라 배우면 좋다고 한다
<< operator를 non-member
function으로 구현해보자
앞에 scope으로 넣어줬던
SimpleVector:: 를 빼준다
그다음 2개의 input을 받아온다
left hand side의 lhs
right hand side의 rhs
로 정의한다
그런다음 왼쪽에 있는
lhs에 rhs를 append해주고
lhs의 reference를 반환해준다
이렇게 non-member function으로
구현해주면 좋은점이 뭘까?
std같은 경우 이미 c++ 내부에서 정의가 되어있어
수정하기가 어려운데, class의 수정없이
함수를 구현할 수 있게 해준다
또한 implict type conversion을
허용할 수 있다
이게 무슨말이냐하면
string helloStr = "Hello";가 있고
helloStr == "Hello"라고 == operator를
사용해줄 경우
만약 string에서 == operator의 Input이
(const string& lhs)로 정의되어있다면
이 == operator는 호출이 안된다
왜냐하면 "Hello"는 string이 아닌
literal이기 때문이다
그래서 string class 내부가 아닌
non-member function으로
정의해주면 type conversion을
컴파일러가 해주기 때문에
위와 같은 연산이 가능해지는 것이다
만약 operator와 피연산자가 모두 같은데
member, non-member 둘 다
정의가 되어있다면
member function이 우선순위를 가진다
operator의 종류이고
필요에따라 정의해주면된다
이렇게 c++의 operator overloading
정리 마무리 ... -!
'강의 > computer science' 카테고리의 다른 글
[computer science] c++의 class와 inheritance(상속), class substitution, virtual function, dynamic binding (1) | 2024.10.18 |
---|---|
[computer science] c++의 Copy/Move semantics, Static (0) | 2024.10.15 |
[computer science] c++의 operator overloading/연산자 구현하기 1편 (0) | 2024.10.14 |
[ComputerScience] c++의 Class와 Class Template (2) | 2024.10.06 |
[ComputerScience] c++의 function overloading (2) | 2024.10.06 |