2026-03-09(월)

조범근·2026년 3월 9일

TIL

목록 보기
14/25

C++ Week 2

Study

STL 기초, 객체지향 설계, 알고리즘 2문제


Today I Learned


1. myMap[1] = 과 insert 방식의 차이

Problem

map<int, string> myMap = { {1, "Apple"}, {2, "Banana"}, {3, "Cherry"} }
myMap[1] =  "Alice"
mymap.insert(make_pair(1, "Alice"));
mymap.insert{(1, "Alice")} 

이렇게 많이 값을 할당 할 수 있는데 어떤 차이 이고, 왜 이렇게 쓸까?

Reason

map<int, string> myMap = { {1, "Apple"}, {2, "Banana"}, {3, "Cherry"} }
myMap[1] =  "Alice"

그냥 대입 방식인 이 두 방법은 기존 값이 있어도 덮어쓴다.

mymap.insert(make_pair(1, "Alice"));
mymap.insert{(1, "Alice")} 

insert는 만약 값이 존재한다면 삽입하지 않음.

Key Point

  • insert는 기존에 들어있는 데이터를 '원본'으로 간주하고 보호해야 할 때 사용.




2. it->first로 표현하는데, it은 메모리 주소 인가??

Problem

cout << it->first << "\n";
보면서 it은 뭔데 포인터의 전유물인 ->을 쓰는거지? 라는 의문점을 갖게 됨.

Reason

결론부터 말하면 진짜 메모리 주소(raw pointer)는 아니다. 하지만 C++ 개발자들은

"컨테이너의 요소를 가리키는 건 포인터와 사용법이 같아야 한다"

그래서 iterator(반복자)는 원본 데이터를 직접 들고 있는 게 아니라 원본을 가리키고 있다.

Key Point

  • 포인터가 사용하는 화살표 연산자를 똑같이 쓸 수 있도록 설계됨

3. .end()는 왜 오류가 안 날까?

Problem

평소에 정의해둔 범위를 넘어가는 배열을 사용하면 오류가 나던게 왜 .end()도 배열의 범위를 넘어간 것인데 오류가 나지 않을까 궁금해졌다

Reason

end()를 쓸때는 end()의 값을 보는게 아니라 "여기는 끝입니다 !" 라는 end()라는 표지판을 보는 거기 때문

Q. end()는 왜 마지막 원소 다음을 가리키도록 설계 됐을까?

  • find를 한다고 하면 실패한 상황을 잘 표현하기 위해 마지막 원소 값이 아닌 end를 반환.

4. reverse iterator 를 사용할 때 base() 가 필요한 이유

Reason

reverse_iterator(역방향 반복자)의 .base()는 "현재 내가 가리키는 위치(현재위치 다음)를 담고 있는 진짜 순방향 화살표(iterator)를 그대로 반환하는 함수"

역방향으로 가고 있을때 distance를 구하려면 begin과 it은 방향이 달라 비교를 하지 못한다. 그래서 it.base()로 순방향 계산으로 바꾸는 것.

근데 왜 distance(.begin(), it.base() - 1)에서 -1을 할까? 그건 바로 it의 순방향 +1을 가리키고 있기 때문이다

Key Point

  • 역방향 반복자일때 distance를 구하려면 it.base() - 1 꼭 하셈 모르면 외워

Reflection

auto it = vec.begin(); 에서 auto는vector<int>::const_iterator를 변환해 준 것
= 가리키는 대상인 vector 내부의 값을 수정할 수 없는 '읽기 전용 iterator(반복자)

객체지향적 설계 SOLID원칙을 확인하며 지키는게 도움이 된다


개념 정리

* vector.pop_back() = 맨 끝 부터 지우는 STL 컨테이너
* vector.erase() = 특정 배열 지울 수 있는 STL 컨테이너

* map<const KEY, Value> = key와 값으로 매칭시키는 STL 컨테이너
   - map<int, string> studentMap = { {101, "Alice"}, {2, "Appel"} }`
   - studentMap[101] = "Alice";
   - mymap.instert(make_pair(1, "Alice"));
   - mymap.instert{(1, "Alice")};
* myMap.find(Key) = map에 존재하는지 확인 가능한 STL 컨테이너
* myMap.clear = 모든 원소를 삭제하는 STL 컨테이너

* sort(Betgin, End) = Begin 부터 End까지 오름차순으로 정렬
- sort(Begin, End, compare) = 여기서 bool compare(int a, int b) { return a > b;}이면 내림차순 정렬

 * `Iterator` = 반복자
  - begin() = 시작원소, end() = 끝 다음 원소
  - rbegin() = 오른쪽 끝 원소, rend() = end()의 반대, 맨 처음 앞 원소
  - it.base() = 현재 내가 가리키는 위치(현재위치 다음)를 담고 있는 순방향 화살표(iterator)를 그대로 반환하는 함수
 * distance(begin(), end()); = 컨테이너 길이
 
 * SOLID 원칙
 	- 단일 책임 원칙(SRP) = 각 클래스는 하나의 책임을 가져야 한다는 원칙
    - 개방 폐쇄 원칙(OCP) = 확장에는 열려 있어야 하고, 수정에는 닫혀있어야 함
    - 리스 코프 치환 원칙(LSP) = 자식 클래스는 부모 클래스에서 기대되는 행동을 보장해야 함
    - 인터페이스 분리 원칙(ISP) = 클라이언트는 자신이 사용하지 않는 메서드에 의존하지 않아야함
    - 의존 역전 원칙(DIP) = 고 수준 모듈은 저수준 모듈에 의존하지 않고 둘다 추상화에 의존해야 한다

0개의 댓글