이 게시글은
서울대학교 데이터사이언스대학원
조요한 교수님의
데이터사이언스 응용을 위한 컴퓨팅 강의를
학습을 위해 재구성하였습니다.
저번 시간에는 c++의 class 내부에서
method를 구현하는 법을 배웠다면
이번시간에는 class의 바깥에서
method 구현하는 법을 정리해보려고한다
그리고 그와 함께
operator overloading까지
같이 정리해보려구한다
그럼 시작..!
Out-of-Class Definition
위 ppt의 코드를 잘 읽어보자
SimpleVector라는 class 내부에
void addElement(T element);
int getSize() const;
와 같이 함수들이 정의되어있는데
자세한 구현은 없이
prototype만 정의되어 있는 것을
확인할 수 있다
실제 메소드들이 어떻게 작동하는지는
class 바깥으로 빼서 정의가 가능하다
class의 바깥에서 정의해주기 위해선
반드시 SimpleVector::와 같은
scope resolution operator를
작성해줘야한다
위는 앞에서는 prototype만 있었던
SimpleVector의 method들을
class 바깥에서 구현한 부분이다
그렇다면 이렇게
class 바깥에 method를
구현하는 것의
장점은 무엇일까?
우선 interface가 simple해진다
그리고
class definition은 header로
구현부는 source file로 구분할 수 있다
이게 왜 장점인가하면
프로그래머가 class를 구현하고
구체적인 implementation을 수정해야할 때
source file만 찾아가서 수정한 뒤
배포하면 되기 때문이다
implementation이 한 개의 파일에 있다면
결국 그 파일을 가져다쓰는
모든 파일들을 전부다 새로 compile해줘야햐는데
위와같은 방식으로 하면
source file만 다시 compile을 해주면 된다
하지만 class template를 쓰는 경우는
메소드의 정의와 implementation이
반드시 같이 있어야한다
그래야 compiler가 동시에 확인을
할 수 있기 때문이다
Class Pointers
class를 pointer로 만들어서
사용하는 방법도 간단하게 알아보자
ppt에는 총 4가지의 방법이
나와있다
제일 처음을 보면
포인터 변수를 선언과 함께
null포인터로 초기화해줬다
기존의 local 변수로 초기화해주거나
선언과 동시에 새로운 object를
dynamic하게 할당해줄 수도 있다
다른 Pointer 변수들과 역시 동일하게
할당을 해줬으면 반드시
delete를 통해서 할당을 해제해줘야한다
아니면
smart pointer를 사용할 수 있다
pointer변수로 정의된
class에는 어떻게 접근할 수 있을까
화살표(->)로 접근하던가
*intVecPtr처럼 작성한 뒤
dot operator(.)로 접근할 수 있다
Operator Overloading
그렇다면 이제
operator overloading에 대해 배워보자
우리가 흔히 쓰는
i++
i--
str1 + str2
cout << intVal
같은 코드에서
++, --, +, << 등을
연산자(operator)라고 부른다
이런 연산자는 일종의
symbol인데
우리가 흔히 알고있는 규칙대로
위 연산자를 쓸 수 있는 이유는
이미 코드 상에 정의가 되어있기 때문이다
또한 프로그래머가 원하는 방식으로
operator가 어떻게 연산되는지
다시 정의를 해줄 수도 있다
이를 operator overloading이라고 한다
우리가 흔히 아는
operator convention이 있다
++는 1 증가
--는 1 감소
+는 두 요소를 합해주기 등
일반적으로 흔히 정의되어있는
convention을 따라가게
정의를 해주면 된다
convention을 따라가게 정의해야
user의 expectation을 맞출 수 있다
프로그래머가 원하는 방식으로
정의를 해도 상관은 없지만
unconventional하게 할 경우
헷갈리는 문제가 발생할 수 있으므로
보통 convention을 따르도록 프로그래밍한다
그럼 이제 차근차근
각 연산자마다
어떻게 실제로 구현을했는지
알아보도록하자
Subscript Operator
우리가 보통 vector의 index요소에 접근할 때
intVec[1]
이러한 방식으로 많이 접근한다
이 때 뒤의 []이 subscript operator이다
구현방법은 위 코드를 참고해보자
우선 외부에서 SimpleVector라는
클래스 내부의 Method를 구현하는 것이므로
반드시 SimpleVector::를 달아준다
그다음 operator[]를 해주면
subscript operator의 구현을
해주겠다는 의미이다
input으로는 int index를 받는다
반환값으로는 T타입을 받아야하니깐
T의 reference값을 준다
그다음 return값으로는
SimpleVector class의
기존에 정의되어있던 array에서
array[index]를 반환해준다
그럼 밑의 main함수와 같이
SimpleVector 에서 vec[2]와 같이
사용할 수가 있다
이제 + 연산자를 구현해보자
operator+를 써준 뒤
반환값으로는 더해진 SimpleVector class자체를
반환해야하므로
SimpleVector<T>를 반환해준다
input으로는 더해야하는 상대(?)로 온
SimpleVector를 넣어준다
그런 다음 구현부를 보자
우선 SimpleVector내 array의 size만큼
새로운 result SimpleVector를 생성해준다
그다음 size만큼 for문을 돌면서
자기 자신과 더해야하는상대 simpleVector의
index 값을 더해주고 result에 넣어준다
그럼 main함수에서
vec1 + vec2를 해주면
vec1과 vec2의 각각의 요소들을 더한
vec3가 정상적으로 나오게 된다
위 operator overloading에서
input을 reference로 주는 이유는
copy를 막기 위해서
주로 사용하는 일종의 tradition이라고 한다
또, 일반적으로 연산자 operation이 끝났을 때
새로운 Object를 반환해주는 것이
+ operator의 convention이라고 한다
+= operator를 구현해보자
operator+=를 해준 뒤
return값으로는 SimpeVector<T>의 reference를
input으로는 상대편(?) SimpleVector의 reference를
그대로 받아온다
그런 다음 size만큼 array를 돌면서
상대편 array의 값을 더해준다음
자기 자신을 그대로 반환한다
이 점에서 새로운 SimpleVector를 반환하는
+와는 다르다고 볼 수 있다
또 하나 주목할점은
input인자로 받아오는 rhs에서
rhs.array에 접근하고있는걸
확인할 수 있는데
SimpleVector의 array는 private이다
이 operator+= 함수는
지금 class 밖에서 구현되고있는데
어떻게 private인 array에 접근이 가능한 것일까?
원칙상으로는 접근이 불가능한게 맞지만
현재 이 method가 SimpleVector내부에서
사용되고 있는 것이기 때문에
이런 경우 C에서 예외적으로 private한 instances에
접근할 수 있도록 허용해준다고 한다
operator++의 구현이다
++가 앞에 쓰여지는 걸
++ Prefix라고 한다
++ prefix의 경우
우선 ++ 연산을 먼저 하고 진행하란 뜻이고
뒤에 나올 ++ postfix의 경우는
우선 진행을 한 뒤 ++ 연산을 하란 뜻이다
아무튼 ++ prefix를 구현해주려면
operator++로 해준다음
return값으로는
더하기 연산이 된 자기 자신을
받아야하므로 SimpleVector reference를 받는다
그다음 size만큼 돌면서
array의 요소들을 한 개씩 증가시켜주면 된다
이번엔 ++ postfix이다
각각 1씩 증가시키는데 postfix기 때문에
증가는 시키지만 증가시키기 전의 값을 반환한다
prefix는 input이 없는데
postfix는 input으로 int를 넣어준다
딱히 큰 의미는 없고
prefix와 postfix를 구분하기 위함이다
prefix와 다른 점은
연산이 되기 전의 array를 반환해야하기때문에
새로운 SimpleVector를 생성해서 반환해야한다
구현부를 보면
temp라는 빈 SimpleVector를 생성한 다음
더하기 전 array요소를 temp에 넣어주고
array요소는 한 개씩 더해준다
그런 다음 temp를 반환한다
내용이 너무 길어져서
1편은 여기까지 ..
2편에는 남은
operator 구현방식과
non-member functions를
다룰 생각이다
'강의 > computer science' 카테고리의 다른 글
[computer science] c++의 Copy/Move semantics, Static (0) | 2024.10.15 |
---|---|
[computer science] c++의 operator overloading/연산자 구현하기 2편 (0) | 2024.10.14 |
[ComputerScience] c++의 Class와 Class Template (2) | 2024.10.06 |
[ComputerScience] c++의 function overloading (2) | 2024.10.06 |
[ComputerScience] c++의 pointer와 reference 3편 (Call by Value, Call by Reference, Reference) (1) | 2024.09.30 |