C++ 템플릿 - 클래스 템플릿

진경천·2023년 10월 30일
0

C++

목록 보기
68/90

클래스 템플릿

template <typename 타입이름>
class 클래스템플릿이름{
	// 클래스 멤버 선언
}

클래스의 일반화된 선언이다.
함수 템플릿과 동작은 같으며, 그 대상이 클래스라는 점만 다르다.

특징

  1. 하나 이상의 템플릿 인수를 가지는 클래스 템플릿을 선언할 수 있다.
  2. 클래스 템플릿에 디폴트 템플릿 인수를 명시할 수 있다.
  3. 클래스 템플릿를 기초 클래스로 하여 상속할 수 있다.

클래스 템플릿을 이용한 Queue 구현

#include <iostream>

using std::cout, std::endl;

template<typename T>
class Queue {
private:
	size_t _size;
	size_t _capacity;
	T* _items;

public:
	Queue()
		: _size(0)
		, _capacity(4)
		, _items(new T[_capacity]) {

	}

	~Queue() {
		delete[] _items;
	}

	void push(T item) {
		if (_size < _capacity) {
			_items[_size++] = item;
		}
		else {
			size_t newCapacity = _capacity * 2;

			T* oldItems = _items;
			T* newItems = new T[newCapacity];

			std::copy(oldItems, oldItems + _capacity, newItems);
			//copy(src 복사를 시작할 배열 주소, src 복사를 끝낼 마지막 배열 주소, dest);

			_capacity = newCapacity;
			_items = newItems;

			delete[] oldItems;

			push(item);
		}
	}

	void cap() {
		cout << "capacity : " << _capacity << endl;
	}

	void pop() {
		--_size;
	}

	T& top() {
		return _items[_size - 1];
	}
};

int main() {
	Queue<int> q0;
	q0.push(1);
	q0.push(2);
	q0.push(4);
	cout << q0.top() << endl;
	q0.pop();
	cout << q0.top() << endl;
	q0.push(4);
	q0.push(4);
	q0.push(4);
	q0.cap();

	Queue<std::string> q1;
	q1.push("abc");
	q1.push("123");
	q1.push("ABC");
	cout << q1.top() << endl;
	q1.pop();
	cout << q1.top() << endl;
}
  • 실행 결과

    4
    2
    capacity : 8
    ABC
    123

매개변수를 사용한 class template

#include <iostream>

using std::cout, std::endl;

template<typename T, int N>
class Queue {
private:
	size_t _size;
	T _items[N];

public:
	Queue()
		: _size(0)
		, _items{} {

	}

	void push(T item) {
		if (_size < N) 
			_items[_size++] = item;
		else 
			throw std::out_of_range("overflow");
	}

	void pop() {
		if (_size == 0)
			throw std::out_of_range("underflow");
		--_size;
	}

	T& top() {
		return _items[_size - 1];
	}
};

int main() {
	Queue<int, 3> q0;
	q0.push(1);
	q0.push(2);
	q0.push(4);
	cout << q0.top() << endl;
	q0.pop();
	cout << q0.top() << endl;

	Queue<std::string, 1> q1;
	try {
		q1.push("abc");
		q1.push("123");
		q1.push("ABC");
		cout << q1.top() << endl;
		q1.pop();
		cout << q1.top() << endl;
	}
	catch (std::out_of_range& e) {
		cout << e.what() << endl;
	}
}
  • 실행 결과

    4
    2
    overflow

함수와 템플릿의 구현 분리

template<typename T, int N>
class Queue {
private:
	size_t _size;
	T _items[N];

public:
	Queue();
	void push(T item);
	void pop();
	T& top();
};

template<typename T, int N>
Queue<T, N>::Queue()
	: _size(0)
	, _items{} {

}

template<typename T, int N>
void Queue<T, N>::push(T item) {
	if (_size < N)
		_items[_size++] = item;
	else
		throw std::out_of_range("overflow");
}

template<typename T, int N>
void Queue<T, N>::pop() {
	if (_size == 0)
		throw std::out_of_range("underflow");
	--_size;
}

template<typename T, int N>
T& Queue<T, N>::top() {
	return _items[_size - 1];
}
  • 실행 결과는 위와 같다.

vector를 이용한 Queue 구현

#include <iostream>
#include <vector>

using std::cout, std::endl;

template<typename T>
class Queue {
private:
	std::vector<T> _items;

public:
	Queue();
	void push(T item);
	void pop();
	T& top();
};

template<typename T>
Queue<T>::Queue()
	: _items{} {

}

template<typename T>
void Queue<T>::push(T item) {
	_items.push_back(item);
}

template<typename T>
void Queue<T>::pop() {
	if (_items.size() == 0)
		throw std::out_of_range("underflow");
	_items.pop_back();
}

template<typename T>
T& Queue<T>::top() {
	return _items.back();
}

int main() {
	Queue<int> q0;
	q0.push(1);
	q0.push(2);
	q0.push(4);
	cout << q0.top() << endl;
	q0.pop();
	cout << q0.top() << endl;

	Queue<std::string> q1;
	try {
		q1.push("abc");
		q1.push("123");
		q1.push("ABC");
		cout << q1.top() << endl;
		q1.pop();
		cout << q1.top() << endl;
	}
	catch (std::out_of_range& e) {
		cout << e.what() << endl;
	}
}
  • 실행 결과

    4
    2
    ABC
    123

profile
어중이떠중이

0개의 댓글