본문 바로가기

C++/STL 및 기타

vector

[c++14 STL 철저입문] 참고

vector 컨테이너

  • 순차열 컨테이너. 길이가 가변적임
  • 순차열의 끝에서만 원소를 추가하거나 삭제 할 수 있음
  • vector 에 할당된 용량(capcaity) 를 초과하는 즉시 더 많은 원소를 저장할 수 있는 추가공간이 자동 할당됨
    -> 크기가 커질때 발생하는 오버헤드나 중간에 원소를 삽입 or 삭제하는 오버헤드를 잘 알고 사용한다면 눈에 띄게 느려지는 일은 없음
  • capacity : 메모리를 추가 할당하지 않아도 저장할 수 있는 원소들의 개수. 실제 원소의 개수를 말하는게 아님
       vector<int> values{1,12,3,5};
    values.reserve(7); //용량을 7로 늘린다.

vector 함수 멤버

reserve()
  • vector 가 수용할 수 있는 메모리를 할당
  • reserve 를 호출한다고 원소가 생성되는 것은 아님. 원소는 없음
  • reserve 호출로 컨테이너에 이미 있는 원소는 영향받지 않음
  • reserve 의 호출로 메모리가 증가했다면, 이미 생성한 iterator는 무효화 됨. 이런 iterator는 반드시 다시 생성행 함
    --> 컨테이너 크기를 늘리는 과정에서 기존 원소들이 새로운 메모리 위치로 복사 or 이동될수 있기 때문
    std::vector v; //원소를 위해 할당된 공간이 없는 상태. 첫번째 데이터를 추가할 때 메모리가 자동 할당됨  
    v.reserve(20) ; // 최소 20개의 원소를 수용할 수 있는 메모리가 할당됨  
    cout << v.size(); //0
    
    //vector 초기크기설정하는 또 다른 방법  
    vector v2(20) // 크기는 int 값 20개이고, default 값이 0인 원소도 20개 있음  
    //이렇게 초기크기로 생성하면 추가 공간의 할당 횟수를 최소화 할수 있음  
    
    veoctr v3(20,99L); //값을 지정해서 초기화도 가능
resize() : vector 원소들의 개수를 변경할 수 있음. capacity 도 늘릴 수 있다.
vector v;  
v.resize(10);

 

push_back() 과 emplace_back()
  • 둘 다 벡터의 뒤에 원소를 추가함
  1. push_back 은 원소를 벡터에 이동시킴
    std::vector<std::string> strs;  
    strs.push_back(string("abcdef")); // str.push_back("abcdef") 랑 같음  
    • 위의 코드는 우측값 참조 매개변수 버전의 push_back 을 호출하게 됨
      string 생성자 호출 & 임시 객체 문자열을 이동시킴 (불필요한 이동과 복사가 발생함)
  1. emplace_back은 벡터에 원소를 생성함
    strs.emplace_back("abcdef")  
    • 내부에서 string 생성자를 호출해 원소를 생성함
    • 생성자를 호출해 컨테이너 내부에서 객체를 생성하므로 push_back 의 이동연산을 하지 않음.

 

clear()

벡터의 원소들을 모두 제거 (size는 변하지만 capacity 는 변하지 않음)

 

pop_back()

벡터의 마지막 원소 제거
원소들 순서 상관없이 원소 제거 하고 싶다면 아래와 같은 방법을 사용 할 수 있음

std::swap(std::begin(data)+1,std::end(data)-1); //두번째 원소와 마지막 원소 교환
data.pop_back(); //마지막 원소 제거

 

erase()
  • 하나 또는 여러개의 원소를 삭제할 수 있음
  • size는 줄어들지만, capacity는 줄어들지 않음
  • 삭제된 원소의 다음 원소를 가리키는 반복자를 return 함.
  • 마지막 원소를 삭제했다면, std::end(data) 를 반환함.
auto iter = data.erase(std::begin(data)+1));// 두 번째 원소를 삭제
auto iter2 = data.erase(std::begin(data)+1,std::begin(data)+3); //2,3 번째 원소 삭제

iter2 는 std::begin(data) +1 이 됨.
범위 지정에서 두번째 인자는 삭제할 원소에서 하나 더 뒤를 가리키는 반복자임!

 

erase() with remove()
  • <algorithm> 에 있는 remove() 함수를 쓰면 범위에서 지정한 값과 일치하는 원소들을 제거 할 수 있음
  • remove 는 실제 원소들을 삭제하진 않음 (size는 그대로임!)
  • 벡터 컨테이너 내부 원소들을 앞으로 이동시키면서, "three" 와 일치하는 원소들을 덮으씌움
  • remove() 연산 이후에도 size는 그대로고, 위의 경우 마지막 두 원소가 빈 string 객체로 치환되어져 있음. \==> 잉여 원소들을 제거하기 위해 벡터의 erase()멤버를 호출해야함
  vector<string> words = {"one", "two", "three","none","three"};
  auto iter = remove(begin(words), end(words), "three");
  words.erase(iter,std::end(words));
  • 처음 두 인수로 지정된 범위 내에서 three 와 일치하는 원소들을 제거함
  • remove 는 삭제후 마지막 원소에서 하나더 가리키는 반복자를 return 함
  • 위 코드를 한 문장으로 하면
    words.erase(remove(begin(words), end(words), "three"), std::end(words));

'C++ > STL 및 기타' 카테고리의 다른 글

c++ idiom  (0) 2020.09.19
Move Semantic  (0) 2020.08.08