[C++] STL Vector (가변 배열) 구현

Kim Dongil·2023년 1월 16일
0

C++

목록 보기
15/23

Vector

std::vector는 c/c++에서 지원하는 배열의 문제 중 하나인 고정 크기 문제를 해결한다. 배열의 경우 한번 정해지면 고정이라 수정하기가 어렵지만, 벡터는 동적 배열 구조 클래스이기 때문에 초기화 과정에 데이터의 크기를 제공하지 않아도 된다.

장점

  • 마지막 위치에 추가나 삭제가 쉬움
  • index 를 이용해서 원하는 값에 직접 접근 가능
  • 동적으로 확장/축소가 가능함

단점

  • 중간 삽입 삭제가 많은 상황에서 비효율적
  • 동적 확장/축소가 편리하긴 하지만, 확장 시의 재할당 비용이 있음 (resize로 메모리 확보 가능)

코드

#pragma once

#include <iostream>
#include <assert.h>

template<typename T>
class CArr
{
private:
	T* m_pData;
	int		m_iCount;
	int		m_iMaxCount;

public:
	void push_back(const T& _iData);
	void resize(int _iResizeCount);
	T* data() { return m_pData; }
	int size() { return m_iCount; }
	int capacity() { return m_iMaxCount; }
	T& operator[] (int idx);

public:
	CArr();
	~CArr();
};

template<typename T>
CArr<T>::CArr()
	: m_pData(nullptr)
	, m_iCount(0)
	, m_iMaxCount(2)
{
	m_pData = new T[2];
}

template<typename T>
CArr<T>::~CArr()
{
	delete[] m_pData;
}

template<typename T>
void CArr<T>::push_back(const T& _Data)
{
	// 힙 영역에 할당한 공간이 다 참 
	if (m_iMaxCount <= m_iCount)
	{
		// 재할당
		resize(m_iMaxCount * 2);
	}

	// 데이터 추가
	m_pData[m_iCount++] = _Data;
}

template<typename T>
void CArr<T>::resize(int _iResizeCount)
{
	// 현재 최대 수용량 보다 더 적은 수치로 확장하려는 경우
	if (m_iMaxCount >= _iResizeCount)
	{
		assert(nullptr);
	}

	// 1. 리사이즈 시킬 개수만큼 동적할당 한다
	T* pNew = new T[_iResizeCount];

	// 2. 기존 공간에 있던 데이터들을 새로 할당한 공간으로 복사시킨다.
	for (int i = 0; i < m_iCount; ++i)
	{
		pNew[i] = m_pData[i];
	}

	// 3. 기존 공간은 메모리 해제
	delete[] m_pData;

	// 4. 배열이 새로 할당된 공간을 가리키게 한다.
	m_pData = pNew;

	// 5. MaxCount 변경점 적용
	m_iMaxCount = _iResizeCount;
}

template<typename T>
T& CArr<T>::operator[](int idx)
{
	return m_pData[idx];
}

int main()
{
	// CArr 객체 생성
	CArr<int> arr;

	// push_back 함수를 사용하여 원소 추가
	arr.push_back(1);
	arr.push_back(2);
	arr.push_back(3);

	// 현재 배열의 크기 및 용량 출력
	std::cout << "Size: " << arr.size() << std::endl;
	std::cout << "Capacity: " << arr.capacity() << std::endl;

	// 배열의 각 원소 출력
	std::cout << "Elements: ";
	for (int i = 0; i < arr.size(); ++i)
	{
		std::cout << arr[i] << " ";
	}
	std::cout << std::endl;

	return 0;
}

정리

알고리즘 문제 풀이에서 vector를 처음 사용해보고 활용해보면서 <>가 무엇인지, 어떤 식으로 기능이 이루어지는지 모르고 사용법만 암기하고 사용했었는데 이번에 구현하고 공부하는 과정에서
포인터 사용하는 법이 조금 더 능숙해졌고 템플릿, 중첩클래스, iterator(반복자), assert.h를 새롭게 알게 됐다.

특히 바로 C++ 로 템플릿 가변 배열 class 를 구현한 것이 아니라
1. c 에서 struct 로 가변 배열 구현
2. c++ 에서 class 로 가변 배열 구현
3. 템플릿으로 전환
3단계로 연이어 구현하면서 클래스와 템플릿, 객체지향에 보다 친숙해진 것 같아서 너무 기쁘다.

C/C++ 강의 59화. STL (vector, list)

0개의 댓글

관련 채용 정보