Language & Framework & GIT/C++

C++ : 제네릭 클래스

veganwithbacon 2023. 7. 19. 10:41
반응형

 

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);

 

반응형