📁 개발 히스토리

C++ - 벡터 클래스 구현하기(1)

일단몸통박치기 2022. 11. 3. 15:04

제가 C++을 할 줄 안다고 했던가요? struct랑 cout 정도는 아는데 말입니다.

 

선행과제로 내준 벡터 클래스 직접 구현하기.

회사는 상상도 못했겠지만 난 벡터를 모른다ㅋ

클래스도 대충 함수를 담을 수 있는 구조체 정도로만 인식하고 있는데.....

 

정말 다행인건 거짓말처럼 이 선행과제 도전하기 하루 전날 알고리즘 책을 사와서 자료구조가 뭔지 이해하고 시작했다.

 

스택이랑 힙. 내가 평상시 쓰는 함수들은 스택에 저장했다가 함수가 종료되면 자동삭제 된다고 한다.

힙은 내가 직접 사이즈를 정해서 저장하고 내가 삭제해주지 않으면 계속 비어있다 -> 이게 '할당'의 뜻이다.

여기서부터 저기까지 자료 저장할 거라고 구역을 정해주는 게 [할당]

 

그러니까 동적 할당은

내가 입력한 사이즈로 자동으로 할당해주는 함수를 만들어써 쓰면 [동적할당]?

뭐 그런 이미지.

 

공식 사이트의 벡터 배열 설명

그러니까 벡터는 내가 정한 형식(int라던지, struct라던지)에 따라 사이즈를 정해서

알아서 동적할당 해주는 클래스다.

 

(추가 설명하자면 벡터는 배열의 형태를 띄고 있다. 그러니까 다른 자료구조-공부한게 링크드 리스트밖에 없음-을 보면 저장 장소가 제각각이어서 다음 노드가 어디있는지 포인터를 넣어놓는 다던지 이런 경우도 있는데 벡터는 무조건 0번 요소 다음에 1번 요소가 들어가야한다.

 

즉, 끝에다 붙이고 떼는 건 대빵 쉬운데 한중간에 있는 요소를 지우면 무조건 뒷 요소들을 한칸씩 땡겨서 다시 순서대로 정렬해줘야한다. 또 벡터의 특징은 size랑 capacity라는 놈이 있는데 size는 실제 배열에 들어가 있는 요소 갯수고 capacity는 여기까지 쓰지 않을까...? 하고 미리 잡아둔 공간이다. 그래서 벡터에 capacity로 잡아둔 공간보다 많은게 들어오면 다시 다른 곳으로 이동해서 capacity 크키를 키우고 순서대로 복사한다. 이 두가지가 일어날때마다 매번 이사해야해서 시간소모가 큰 것이 단점이다.)

 

 

 

음, 뭐하는 놈인지는 이제 알겠고 그럼 얘가 어떻게 힙에 자리를 할당하는 걸까?

찾아보니 malloc과 new라는 놈이 있었다. 아무래도 malloc이 더 많이 쓰이는 거 같고 new가 새로 나온 놈 같은데그놈의 malloc, 왜 그렇게 문제가 많은지 초반부여서 기억도 잘 안나는데 기냥 작동을 안해가지고다른 사람들이 구현한 벡터 클래스를 보며 참고하려던 건 때려치고 그냥 new로 내가 직접 돌 깎아서 쓰기로 했다.

 

어쨋든 기본적으로 작동하기 위해 필요한 놈들이다.

여기서부터 벌써 멘붕이지.

생성자, 복사생성자, 할당연산자, 소멸자. 전부 처음 들어보는 거였다.

 

이 벡터라는 함수 모음집

(지금까지 잘 모르지만 자주 썼었던 transform 이것도 다 벡터같은 클래스였구나를 다 끝나고야 이해했다)

이 작동하기 위해 가장 기초적인 부분이라고 생각하면 된다.

 

가장 위의 생성자는 클래스명(); 를 쓰면 이 클래스는 배열이니까 배열 요소를 만들고 초기화해야한다(필수!)

 

세번째는 클래스명 = 클래스명 을 쓰면 오른쪽 클래스를 왼쪽 클래스값에 넣으라는 얘기니까

"=" 연산자를 오버로딩해서(ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ첨에 상상도 못함)

만약에 [ = 클래스명 ] 같은 상황이 생기면 이 함수가 실행되는거다.

오른쪽이랑 똑같은 값이지만 allocation(내가만든 함수인데 temp값으로 arr 새로 만들어서 할당해주는 자동함수다)를 써서

새로운 장소에 같은 값의 배열을 만들어준다.

return *this가 있는 이유는 새로 만든 배열의 포인터를 리턴해서 왼쪽에 대입해야되기 때문이다.

 

복사 생성자보다 할당연산자를 먼저 설명한 이유가 말하자면 둘다 원래 있는 걸 복사하는 건 똑같다.

 MyVector<MyObject> test2(test); 는 복사생성자고

test2 = test; 가 할당 연산자다

 

즉, 복사 생성자는 생성될때 원래 있는걸 복사해서 쓰는거라 할당만 새로 해주면 되는데

할당 연산자는 원래 가지고 있던 값이 있어서 무작정 할당만 하면 원래 자료가 삭제가 안되고 남아있다(거지같은 힙 특징)

그래서 중간에 delete[] arr;을 통해서 원래값을 지워버리고 다시 할당해야만 한다.

 

그리고 소멸자가 ~클래스명 인데 사실 이건 작동하는지 안봄. 아니 뭐 어케 해야 삭제되는지 모르고

삭제 시켜도 확인할 시간도 정신머리도 없었기때문에 걍 일케하면 삭제 된다길래ㅋㅋ...ㅠ

 

 

가장 기초적인거만 설명했는데 벌써 분량이 이만치다

이걸 2일? 3일만에 했는데 얼마나 삽질을 했을지 상상이 되는 부분이다.

아는게 0인데도 마치 1인냥.

앞으로의 삶의 모토가 이게 될것만 같다.