iterator
헷갈리는 부분
- const_iterator it 이라고 선언하면 *it의 값, 즉 내용물만 못 바꾸는 것이지 it++은 가능하다.
- iterator 연산이 불가능하게 하려면 const const_iterator it 또는 const iterator를 사용한다.
- const auto it = v.begin(); 처럼 쓰면 it++ 불가능한 반복자가 지정된다.
- 내용물이 안 바꿔지게 하려면 auto it = v.cbegin()을 써야한다. crbegin()도 있다.
- cend()도 있다. 보통 end()만 써도 되지만, 읽기전용임을 명시하는 cend()가 더 명확하고 안전하다.
반복문에서 복사와 참조
auto (복사)
for (auto x : v)
매 반복마다
vector 원소 → 새 변수 복사
예
vector<string>
이면
문자열 복사 발생
const auto& (참조)
for (const auto& x : v)
동작
원본을 그대로 참조
복사 없음
복사 없음
그래서 훨씬 빠름
얕은 복사가 이루어지는 대입, 깊은 복사가 이루어지는 대입
얕은 복사가 되는 경우 (Shallow Copy)
포인터 주소만 복사하는 경우.
① 일반 포인터
int* p1 = new int(10);
int* p2 = p1;
int* p2 = p1;
구조
p1 ─┐
├──> 10
p2 ─┘
├──> 10
p2 ─┘
그래서
*p2 = 20;
하면
*p1 = 20
② shared_ptr
auto p1 = std::make_shared<int>(10);
auto p2 = p1;
auto p2 = p1;
구조
p1 ─┐
├──> int(10)
p2 ─┘
├──> int(10)
p2 ─┘
차이점
참조 카운트 증가
사실 복사라기보다는 공동 소유에 가까움.
③ weak_ptr
weak_ptr<int> w1 = p1;
weak_ptr<int> w2 = w1;
weak_ptr<int> w2 = w1;
얕은 복사지만
참조 카운트 증가 안함
깊은 복사가 되는 경우 (Deep Copy)
객체 자체의 데이터를 복사하는 경우입니다.
즉 새로운 메모리를 만들고 데이터를 복사합니다.
대표적인 경우
① STL 컨테이너
std::vector<int> v1 = {1,2,3};
std::vector<int> v2 = v1;
std::vector<int> v2 = v1;
구조
v1 → [1 2 3]
v2 → [1 2 3]
v2 → [1 2 3]
메모리
서로 다른 메모리
그래서
v2[0] = 10;
결과
v1 = {1,2,3}
v2 = {10,2,3}
v2 = {10,2,3}
② 일반 객체 (값 타입)
struct A {
int x;
};
A a1{10};
A a2 = a1;
int x;
};
A a1{10};
A a2 = a1;
구조
a1.x = 10
a2.x = 10
a2.x = 10
서로 독립입니다.
③ std::string
std::string s1 = "hello";
std::string s2 = s1;
std::string s2 = s1;
문자열 데이터도 복사됩니다.
'코딩 학습 > C와 C++' 카테고리의 다른 글
| C++ 기초 - 디자인 패턴(싱글톤, 데코레이터, 옵저버) (0) | 2026.03.17 |
|---|---|
| C++ 기초 - 객체지향 설계 (1) | 2026.03.16 |
| C++ 기초 오답노트 / 기능 정리 (0) | 2026.03.12 |
| C++ 기초 - 템플릿 (0) | 2026.03.11 |
| C++ 기초 - 자원 관리 (0) | 2026.03.10 |