728x90
템플릿
[ 일반화와 템플릿 ]
- 제네릭 (generic) : 함수나 클래스를 일반화시키고, 매개 변수 타입을 지정하여 틀에서 찍어 내듯이 함수나 클래스 코드를 생산하는 기법
- 템플릿 : 함수나 클래스를 일반화하는 C++ 도구로, template 키워드를 사용하여 함수나 클래스 선언
- 제네릭 타입 : 일반화를 위한 데이터 타입
[ 템플릿으로부터의 구체화 ]
- 구체화 (specialization) : 템플릿 함수로부터 구체화된 함수의 소스코드를 생성
#include <iostream>
using namespace std;
class Circle {
int radius;
public:
Circle(int radius=1) { this->radius = radius; }
int getRadius() { return radius; }
};
template <class T>
void myswap(T &a, T &b) {
T tmp;
tmp = a;
a = b;
b = tmp;
}
int main() {
int a=4, b=5;
myswap(a, b); // myswap(int& a, int& b) 함수 구체화 및 호출
cout << "a=" << a << "," << "b=" << b << endl;
double c=0.3, d=12.5;
myswap(c, d); // myswap(double& a, double& b) 함수 구체화 및 호출
cout << "c=" << c << "," << "d=" << d << endl;
Circle donut(5), pizza(20);
myswap(donut, pizza); // myswap(Circle& a, Circle& b) 함수 구체화 및 호출
cout << "donut 반지름 = " << donut.getRadius() << ",";
cout << "pizza 반지름 = " << pizza.getRadius() << endl;
}
[ 구체화 오류 ]
- 제네릭 타입에 구체적인 타입 지정 시 주의
[ 템플릿 장점과 제네릭 프로그래밍 ]
템플릿 장점 )
- 함수 코드의 재사용 : 높은 소프트웨어의 생산성과 유용성
템플릿 단점 )
- 포팅에 취약 : 컴파일러에 따라 지원하지 않을 수 있음
- 컴파일 오류 메시지 빈약, 디버깅에 많은 어려움
제네릭 프로그래밍 )
- 제네릭 함수나 제네릭 클래스를 활용하는 프로그래밍 기법으로 일반화 프로그램이라고도 부름
- C++에서 STL (Standard Template Library) 제공하여 활용
- 보편화되는 추세
제네릭 함수 예제
{ 예제 10-4 배열을 복사하는 제네릭 함수 mcopy() 함수 만들기 연습 }
#include <iostream>
using namespace std;
// 두 개의 제네릭 타입 T1, T2를 가지는 copy()의 템플릿
template <class T1, class T2>
void mcopy(T1 src [], T2 dest [], int n) { // src[]의 n개 원소를 dest[]에 복사하는 함수
for(int i=0; i<n; i++)
dest[i] = (T2)src[i]; // T1 타입의 값을 T2 타입으로 변환한다.
}
int main() {
int x[] = {1,2,3,4,5};
double d[5];
char c[5] = {'H', 'e', 'l', 'l', 'o'}, e[5];
// mcopy()의 T1은 int로, T2는 double로 구체화
mcopy(x, d, 5); // int x[]의 원소 5개를 double d[]에 복사
// mcopy()의 T1, T2 모두 char로 구체화
mcopy(c, e, 5); // char c[]의 원소 5개를 char e[]에 복사
for(int i=0; i<5; i++) cout << d[i] << ' '; // d[] 출력
cout << endl;
for(int i=0; i<5; i++) cout << e[i] << ' '; // e[] 출력
cout << endl;
}
제네릭 클래스와 예제
[ 제네릭 클래스 ]
- 제네릭 클래스 선언
- 제네릭 클래스 구현
- 클래스 구체화 및 객체 활용
{ 예제 10-7 제네릭 스택의 제네릭 타입을 포인터나 클래스로 구체화하는 예 }
#include <iostream>
#include <string>
using namespace std;
/* 이 부분에 예제 10-6에 작성한 MyStack 템플릿 클래스 코드가 생략되었음 */
class Point {
int x, y;
public:
Point(int x=0, int y=0) { this->x = x; this->y = y; }
void show() { cout << '(' << x << ',' << y << ')' << endl; }
};
int main() {
MyStack<int *> ipStack; // int* 만을 저장하는 스택
int *p = new int [3];
for(int i=0; i<3; i++) p[i] = i*10; // 0, 10, 20으로 초기화
ipStack.push(p); // 포인터 푸시
int *q = ipStack.pop(); // 포인터 팝
for(int i=0; i<3; i++) cout << q[i] << ' '; // 화면 출력
cout << endl;
delete [] p;
MyStack<Point> pointStack; // Point 객체 저장 스택
Point a(2,3), b;
pointStack.push(a); // Point 객체 a 푸시. 복사되어 저장
b = pointStack.pop(); // Point 객체 팝
b.show(); // Point 객체 출력
MyStack<Point*> pStack; // Point* 포인터 스택
pStack.push(new Point(10,20)); // Point 객체 푸시
Point* pPoint = pStack.pop(); // Point 객체의 포인터 팝
pPoint->show(); // Point 객체 출력
MyStack<string> stringStack; // 문자열만 저장하는 스택
string s="c++";
stringStack.push(s);
stringStack.push("java");
cout << stringStack.pop() << ' ‘;
cout << stringStack.pop() << endl;
}
728x90
'Programming > C++' 카테고리의 다른 글
[C++ 스터디] 템플릿과 표준 템플릿 라이브러리{STL}_(2) (0) | 2022.12.08 |
---|---|
[C++ 스터디] 상속(1) (1) | 2022.11.27 |
[C++ 스터디] static 멤버 (0) | 2022.11.20 |
[C++ 스터디] 참조리턴 / 복사 생성자 / 함수 중복 (0) | 2022.11.13 |
[C++ 스터디] 객체 치환 및 객체 리턴 | Vector (0) | 2022.11.06 |