코딩 학습/C와 C++

C++ 헷갈리는 개념 정리

이개 2026. 3. 13. 20:40

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;
 

구조

p1 ─┐
├──> 10
p2 ─┘
 

그래서

 
*p2 = 20;
 

하면

*p1 = 20
 

② shared_ptr

 
auto p1 = std::make_shared<int>(10);
auto p2 = p1;
 

구조

p1 ─┐
├──> int(10)
p2 ─┘
 

차이점

참조 카운트 증가
사실 복사라기보다는 공동 소유에 가까움.
 

③ weak_ptr

 
weak_ptr<int> w1 = p1;
weak_ptr<int> w2 = w1;
 

얕은 복사지만

참조 카운트 증가 안함

깊은 복사가 되는 경우 (Deep Copy)

객체 자체의 데이터를 복사하는 경우입니다.
새로운 메모리를 만들고 데이터를 복사합니다.

대표적인 경우

① STL 컨테이너

 
std::vector<int> v1 = {1,2,3};
std::vector<int> v2 = v1;
 

구조

v1 → [1 2 3]
v2 → [1 2 3]
 

메모리

서로 다른 메모리
 

그래서

 
v2[0] = 10;
 

결과

v1 = {1,2,3}
v2 = {10,2,3}
 

② 일반 객체 (값 타입)

 
struct A {
int x;
};

A a1{10};
A a2 = a1;
 

구조

a1.x = 10
a2.x = 10
 

서로 독립입니다.


③ std::string

 
std::string s1 = "hello";
std::string s2 = s1;
 

문자열 데이터도 복사됩니다.