본문 바로가기
Language & Framework & GIT/C++

C++ : 제네릭 클래스

by veganwithbacon 2023. 7. 19.
반응형

 

template을 통한 제네릭 클래스(generic class) 

일반적으로 스택을 통해 저장되는 클래스들은 데이터의 타입만 다를 뿐, 알고리즘은 동일하다.

template을 통해 스택에 저장되는 데이터 타입을 일반화시킨 제네릭 스택 클래스를 만들자.

 

✅Generic class 

: 위 클래스를 만들기 위해서는 클래스 선언부와 구현부를 모두 template으로 선언해야한다.

  제네릭 클래스의 멤버 함수는 자동 제네릭 함수이다.

 

▶제네릭 클래스 선언부

스택은 하나의 데이터 타입만을 다루기 때문에 제네릭 타입은 T하나만 필요하다.

template <class T>
class MyStack {
	int tos;
    T data[100]; //T타입의 배열. 스택에 최대 100개의 원소 저장
public:
	MyStack();
    void push(T element); // T타입 원소 element를 data[]에 푸시
    T pop(); // 스택의 탑에 있는 원소를 data[] 에서 팝하여 리턴
};

값이 저장되는 스택 공간 data []를 T타입으로 선언하고, push()의 매개 변수와 pop()의 리턴 타입도 T로 선언한다.

 

▶제네릭 클래스 구현부

클래스 구현부는 멤버 함수를 작성하는 곳,

클래스 명은 MyStack 대신 MyStack<T>로 사용하고, 각 멤버 함수 앞에 template <class T>를 붙여 제네릭함수라고 한다.

template <class T>
void MyStack<T>::push(T element) {
~~
}
template <class T> T MyStack<T>::pop(){ // 한 줄에 선언가능
~~
}

 

▶제네릭 클래스 구체화

제네릭 클래스를 이용할 때는 클래스의 이름과 함께 제네릭 타입 T에 적용할 구체적인 타입을 지정해야 한다.

MyStack<int> iStack; // int 타입을 다루는 스택 객체 생성
MyStack<double> dStack; // double 타입을 다루는 스택 객체 생성

컴파일러는 이 선언문으로부터 구체화 과정을 진행

  1.  MyStack 템플릿의 T에 int나 double을 적용하여 두 개의 구체화된 버전의 C++ 클래스 소스(specialized class)를 생성한다.
  2. 두 C++클래스를 컴파일하고 iStack 객체와 dStack 객체를 생성하도록 컴파일한다.

구체화를 시킨 iStack과 dStack은 보통 객체처럼 사용하면 된다.

iStack.push(3);
int n = iStack.pop();

dStack.push(3.5);
double d = dStack.pop();

제네릭 클래스의 포인터를 선언하고 동적으로 객체를 생성할 수도 있다.

 MyStack<char> *p = new MyStack<char>();
 p->push('a');
 char C = p -> pop();
 delete p;
더보기

>>함수의 매개 변수 타입이 제네릭 클래스일 경우

함수의 매개 변수 타입 제네릭 클래스일 때,

void popAll(MyStack<int> s){~~}

MyStack<int> iStack;
popAll(iStack);

 

popAll() 함수가 실행되면 iStack 객체를 복사해 객체 s가 생긴다. 다음과 같이 참조 매개 변수를 사용해 객체 복사의 오버헤드를 제거할 수 있따.

void popAll(MyStack<int> &r) {~~} //매개변수 r: int 타입의 MyStack 객체의 참조

popAll(iStack);

 함수의 매개 변수로 제네릭 객체의 포인터 선언 가능

void popAll(MyStack<int> *p); //매개변수 p: int 타입의 MyStack 객체의 포인터

popAll(&iStack);

 

반응형

댓글