[Basic C++] #33_Vector, 순차 컨테이너
C++ 개발에서 표준 라이브러리(STL)의 Vector에 대해 알아보겠습니다.
"전문가를 위한 C"의 16 항목, "컨테이너와 반복자 이해하기"에 해당하는 내용입니다.
Overview
- 개념
- 초기화
- 복제, 대입
- 접근
- 삽입, 제거
- 크기, 용량
- 이동 시맨틱
#0. 개념
- vector는 STL 컨테이너이며, 순차 컨테이너입니다.
- 여느 STL 컨테이너처럼, 템플릿 클래스이며, "항목 타입"과 "할당자 타입" 등 두 개의 파라미터를 인자로 받습니다.
- 저장된 항목들은 연속된 메모리에 저장되고, 각 항목은 인덱스를 통해 접근 가능합니다.
#1. 초기화
#include <vector>
// 디폴트 생성자
vector<int> intVector1; // 항목 개수: 0
vector<int> intVector2 (10); // 항목 개수: 10, 항목 값: 0
vector<int> intVector3 (10, 100); // 항목 개수: 10, 항목 값: 100
// initializer_list 사용
vector<int> intVector4 ({1, 2, 3, 4, 5}); // 항목 개수: 5, 항목 값: 1, 2, 3, 4, 5
vector<int> intVector5 = {1, 2, 3, 4, 5};
vector<int> intVector6{1, 2, 3, 4, 5};
Details
- Vector의 디폴트 생성자는 0개의 항목을 가지는 vector 컨테이너를 생성합니다.
- 항목의 경우 초깃값을 설정하지 않으면, "int" 혹은 "char"같은 정수형 내장 기본 타입은 0으로 초기화되고,
- "float"같은 부동 소수점형 내장 기본 타입은 0.0으로 초기화됩니다.
- * 기본적으로 항목 개수, 각 항목의 값 순서로 기억합니다.
#1. 복제, 대입
// 기존의 저장된 항목들 모두 삭제 후 대입, assign()
intVector.assign(5, 100); // 항목 개수 10 -> 5, 항목 값: 100 for *
// 기본의 저장된 항목들 모두 삭제 후 대입, assign() w/ initializer_list
intVecotr.assign({1, 2, 3, 4}); // 항목 개수 5 -> 4, 항목 값: 1, 2, 3, 4
// swap 메서드
vector<int> intVector1(10, 0); // 항목 개수: 10, 항목 값: 0 for *
vector<int> intVector2(5, 100); // 항목 개수: 5, 항목 값: 100 for *
intVector1.swap(intVector2); // intVector1 < - > intVector2
Details
- vector에서 항목을 삽입하기 위해 "assign()" 메서드도 제공합니다.
- "assign()" 메서드는 기존에 저장된 항목들을 모두 삭제하고, 새로운 항목들을 삽입합니다.
- 더불어, "assign()" 메서드에도 "initializer_list"를 사용할 수 있습니다.
- 추가적으로, vector는 "swap()" 메서드를 활용해 두 개의 vector 컨테이너 간의 교환을 가능하게 합니다.
#2. 접근
vector<int> v(10, 100); // 항목 개수: 10, 항목 값: 100 for *
// 1. operator[INDEX]: INDEX의 항목을 참조합니다.범위를 점검하지 않습니다.
v[0];
// 2. at(INDEX): INDEX의 항목을 참조합니다. 범위를 점검합니다.
v.at(0);
// 3. front(): 첫 번째 원소를 참조합니다.
v.front();
// 4. back(): 마지막 원소를 참조합니다.
v.back();
// 5. begin(): 첫 번째 원소를 가리키는 "반복자"를 리턴합니다.
v.begin();
// 6. end(): 마지막 원소의 다음을 가리키는 "반복자"를 리턴합니다.
v.end();
Details
- vector는 기존의 배열과 똑같이 "operator [INDEX]"를 통해 항목에 접근할 수 있습니다.
- 더불어, vector 컨테이너는 "at()" 메서드를 제공합니다.
- "operator []"와 "at()"의 결과는 같지만, 차이점이 존재합니다.
1. "operator[]"의 경우, 범위를 점검하지 않기 때문에 탐색 속도가 빠릅니다.
2. "at()"의 경우, 범위 점검을 수행하기 때문에 탐색 속도가 느리지만 안전합니다.
- 그 외에도 "front" 혹은 "back"을 통해 첫 번째 혹은 마지막 항목을 참조할 수 있습니다.
- 이때, "begin"과 "front", 그리고 "end"와 "back"의 차이점도 존재합니다.
- * "begin"과 "end"는 항목을 가리키는 반복자를 참조하고, "front"와 "back"은 항목을 참조합니다.
#3. 삽입, 제거
vector<int> v(10, 100);
// 1. clear(): 모든 원소를 제거하고, 메모리는 남깁니다.
v.clear();
// 2. push_back(DATA): 마지막 항목 바로 뒤에 새로운 항목을 추가합니다.
v.push_back(5);
// 3. pop_back(): 마지막 항목을 제거합니다.
v.pop_back();
/* 4. insert()
: a) insert (const_iterator 위치, const T& x)
b) insert (const_iterator 위치, size_t 개수, const T& x)
c) insert (const_iterator 위치, iterator 범위 시작, iterator 범위 끝)
*/
auto it = begin(v);
v.insert(++it, 3, 4)
// 5. erase(Iter): Iter 반복자가 가리키는 항목을 제거합니다.
for(auto it = v.begin(); it != v.end(); ++it)
if(*it == 100)
v.erase(it);
// 6. empty(): vector 컨테이너가 비어있다면 true를 반환합니다.
if(v.empty() == true)
cout << "vector is empty!" << endl;
Details
- 위 코드 예제를 살펴보면 기본적인 삽입, 그리고 삭제 작업을 수행할 수 있습니다.
- 짚고 넘어가야할 점은, "erase()"의 경우 반복자를 인자로 받는다는 점입니다.
#4. 크기, 용량
// size(): 항목의 개수를 반환합니다.
size_t vectorSize = v.size();
// capacity(): 할당된 메모리 공간의 크기를 반환합니다.
size_t vectorCapacity = v.capacity();
Details
- "size"와 "capacity"의 차이점은 중요합니다!
- "size"의 경우 항목의 개수를 반환하지만, "capacity"는 할당된 총메모리의 크기를 반환합니다.
#5. 이동 시맨틱
// 우측값 참조
class A
{
public:
A(int i, const std::string& str): myInt(i), myStrt(str){}
private:
int myInt;
std::string myStr;
};
vector<A> v;
A myClass(12, "Twelve");
v.push_back(myClass); // 오버헤드가 발생!!
v.push_back(std::move(myClass)); // 이동 시맨틱 활용, 오버헤드 감소
or
v.push_back(A(12, "Twelve")); // 임시 객체를 바로 넘기는 방법
Details
- "vector" 컨테이너는 push_back(const T& val)의 이동 시맨틱 버전 push_back(const T&& val)을 정의합니다.
- 이동 시맨틱 버전의 push_back은 복제가 일어나지 않기 때문에, 오버헤드 문제를 피할 수 있습니다.
#6. emplace, 생성 삽입
v.emplace_back(12, "Twelve");
Details
- "emplace" 메서드는 복제나 이동 없이 즉석에서 객체를 생성하고 삽입합니다.
'언어 > Basic C++' 카테고리의 다른 글
[Basic C++] #35_list, 순차 컨테이너 (0) | 2022.06.19 |
---|---|
[Basic C++] #34_반복자, 반복자의 활용 (0) | 2022.06.17 |
[Basic C++] #32-3_STL 정렬 알고리즘 (0) | 2022.06.05 |
[Basic C++] #32-2_STL 탐색 알고리즘 (0) | 2022.06.04 |
[Basic C++] #32-1_STL 알고리즘 (0) | 2022.06.04 |