본문 바로가기

[ C/ C++ 프로그래밍 ]/[ STL ]

[ 혼연 정리 ] 시퀀스 컨테이너 - 2 [ 벡터 ]


◎ 벡터의 삽입과 삭제

 - 각 컨테이너별로 내부적 구조가 다르다 -> 삽입, 삭제 방식도 컨테이너별로 다르다.
 - 다르기 때문에 삽입, 삭제는 일반함수보다는 컨테이너 멤버함수로 제공
 - 벡터의 제일 끝 부분에서 삽입, 삭제 수행


◎ 멤버 함수

  ㅇ void push_back(const T& x);      
     - 벡터 끝에 새 요소  x를 추가하고 필요할 경우 메모리관리를 한다.

  ㅇ void pop_back();




 - 앞쪽에서 요소를 삽입, 삭제하는 push_front, pop_front 함수는 제공 하지 않음

 
ㅇ insert() 함수
 
- insert 함수를 사용해서 중간에 요소 삽입은 가능
- 삽입하기 전에 메모리가 부족할 경우 재할당 하여 늘린다.

  iterator insert (iterator it, const T& x = T() );
  void insert (iterator it , size_type n, const T& x);
  void insert(iterator it, const_iterator first, const_iterator last); 

 ※    iterator   it  :삽입 위치 반복자

ㅇ erase() 함수
 - 반복자가 지정하는 요소 하나 또는 반복자 구간을 삭제 한다.

 iterator erase(iterator it);
 iterator erase(iterator fisrt, iterator last);

- 예제

1 #include <iostream>
2 #include <vector>
3
4 using namespace std;
5
6 template <typename C>
7 void dump(const char *desc, C c)

8 {
9     cout.width(12);
10     cout << left << desc << "==> " ;
11     copy(c.begin(), c.end(), ostream_iterator<typename C::value_type>(cout," "));
12     cout << endl;
13 }
14
15 void main()
16 {
17     const char *str = "0123456789";
18     vector<char> vc(&str[0], &str[10]);
19     dump("생성직후",vc);
20    
21     vc.push_back('A');
22     dump("A 추가", vc);
23
24     vc.insert(vc.begin()+3 , 'B');
25     dump("B 삽입", vc);
26
27     vc.pop_back();
28     dump("끝요소삭제",vc);
29
30     vc.erase(vc.begin()+5, vc.begin()+8);
31     dump("5~8 삭제", vc);
32 }



ㅇ 다른 컨케이너와 요소 교환하기

 - 반복자 구간을 인수로 취하는 insert함수를 사용하면 다른 컨테이너의 구간에 있는 요소를 벡터에 삽입가능
 - 다른 컨테이너들도 똑같은 원형의 insert함수를 제공하므로 벡터의 구간을 다른 컨테이너로 복사하는 것도 가능



 - 예제

1 #include <iostream>
2 #include <vector>
3 #include <list>
4 #include <algorithm>
5
6 using namespace std;
7
8 template <typename C>
9 void dump(const char *desc, C c)

10 {
11     cout.width(12);
12     cout << left << desc << "==> " ;
13     copy(c.begin(), c.end(), ostream_iterator<typename C::value_type>(cout," "));
14     cout << endl;
15 }
16
17 void main()
18 {
19     list<int> li;
20     for ( int index = 0 ; index < 100 ; index++ )
21     {
22         li.push_back(index);
23     }
24     vector<int> vi;
25
26     vi.insert(vi.begin(), find(li.begin(), li.end(), 8), find(li.begin(), li.end(), 25));
27     dump ("추가후",vi);
28 }





ㅇ 반복자 무효화 현상

 - 반복자는 한번 설정하면 계속 같은 요소를 가리킴
 - 컨테이너에 삽입, 삭제가 일어나면 메모리 재할당 및 이동이 발생 -> 반복자가 무효화 될 수 있음
 - 반복자가 더 이상 정확한 요소를 가기키지 못하는 것



 -  삭제시 삭제 구간의 뒤쪽은 무효화, 앞쪽은 영향 받지 않음
 -  삽입된 위치의 앞쪽은 무효화 될수도 있고 안될수 있다. (재할당에 의해 메모리가 바뀌면 무효화)

- 예제

 1 #include <iostream>
2 #include <vector>
3 #include <algorithm>
4
5 using namespace std;
6
7 void main()
8 {
9 vector<int> vi;
10     for (int index = 0 ; index < 80 ; index++ )
11     {
12         vi.push_back(index);
13     }
14
15     vector<int>::iterator it;
16     it = find(vi.begin(), vi.end(), 55);
17    
18     cout << *it << endl;
19     //vi.erase(it-1);  // 무효화발생
20     vi.insert(vi.begin(), 1234); // 무효화발생
21     cout << *it << endl;
22 }

 - 컨테이너에 조금이라도 변형을 가했다면 이전에 조사해 놓은 반복자를 믿지 않는 편이 더 확실하다.

ps : 출처 및 자세한 내용은  www.WinAPI.co.kr 참고