본문 바로가기

문과 코린이의, [C. C++] 기록/C++ 이론

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (Point 클래스 템플릿과 배열 클래스 템플릿, 특정 템플릿 클래스의 객체를 인자로 받는 일반함수의 정의와, friend 선언)

반응형

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (Point 클래스 템플릿과 배열 클래스 템플릿, 특정 템플릿 클래스의 객체를 인자로 받는 일반함수의 정의와, friend 선언)

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (Point 클래스 템플릿과 배열 클래스 템플릿, 특정 

템플릿 클래스의 객체를 인자로 받는 일반함수의 정의와, friend 선언)


 * 이 포스팅의 '3.배열 클래스의 템플릿화'를 기반으로 확장된 예제를 풀어나가보자 함.

 

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (클래스 템플릿의 정의, 클래스 템플릿

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (클래스 템플릿의 정의, 클래스 템플릿의 선언과 정의의 분리, 배열 클래스의 템플릿화) 1. 클래스 템플릿의 정의 [문과

vansoft1215.tistory.com

 

1. Point 클래스 템플릿과 배열 클래스 템플릿

Case 1 )

[ PointTemplate.h ]

#pragma once

#ifndef __POINT_TEMPLATE_H_
#define __POINT_TEMPLATE_H_

template <typename T>
class Point
{
private:
	T xpos, ypos;
public:
	Point(T x = 0, T y = 0);
	void ShowPosition()const;
};

template<typename T>
Point<T>::Point(T x, T y) :xpos(x), ypos(y) { }

template<typename T>
void Point<T>::ShowPosition()const {
	cout << '[' << xpos << ", " << ypos << ']' << endl;
}

#endif

 

[ ArrayTemplate.h ]

#pragma once

#ifndef __ ARRAY_TEMPLATE_H_
#define __ ARRAY_TEMPLATE_H_

#include<iostream>
#include<cstdlib>
using namespace std;

template <typename T>
class BoundCheckArray
{
private:
	T* arr;
	int arrlen;

	/* 깊은 복사가 진행될 수 있도록, 복사생성자와 대입연산자를 private 맴버로 두면서 복사와 대입을 막는다.*/
	// 배열은 저장소의 일종이며, 저장소에 저장된 데이터는 '유일성'이 보장되어야 하기 때문에, 대부분의 경우 배열에서의 복사는 불필요하거나 잘못된 일로 간주하곤 한다.
	BoundCheckArray(const BoundCheckArray& arr) { } // 복사생성자
	BoundCheckArray& operator=(const BoundCheckArray& arr) { } // 대입연산자

public:
	BoundCheckArray(int len); // 생성자
	T& operator[] (int idx); // 배열 연산자
	T operator[](int idx)const; // const 배열 연산자
	int GetArrLen() const; // arrlen : 배열의 길이 반환 함수
	~BoundCheckArray(); // 소멸자
};


template<typename T>
BoundCheckArray<T>::BoundCheckArray(int len) :arrlen(len) { // 생성자
	arr = new T[len]; // 힙에 배열만큼의 메모리 공간 마련
}

template<typename T>
T& BoundCheckArray<T>::operator[] (int idx) { // 배열 연산자
	/* iarr[i] = iarr.operator[](i) */
	if (idx < 0 || idx >= arrlen) { // 잘못된 배열 접근을 막기 위한, 안전성 보장 코드
		cout << "Array index out of bound exception" << endl;
		exit(1); // 에러시 강제 종료 
	}
	return arr[idx]; // 배열 요소의 참조값이 반환됨
}

template<typename T>
T BoundCheckArray<T>::operator[] (int idx) const { // const 맴버함수 추가 배열 연산자
// const 매개변수가 있는 함수가 사용될 예정인 경우, operator[]함수 또한 const로 사용되어야 한다.
// 따라서 이러한 경우 따로 정의를 해 줄 필요가 있다.
	if (idx < 0 || idx >= arrlen) {
		cout << "Array index out of bound exception" << endl;
		exit(1);
	}
	return arr[idx];
}

template <typename T>
int BoundCheckArray<T>::GetArrLen() const { // 배열의 길이 반환 함수
	return arrlen;
}

template <typename T>
BoundCheckArray<T>::~BoundCheckArray() { // 소멸자
	delete[]arr; // 배열 메모리 해제
}


#endif

 

[ Main ]

#include<iostream>
#include "ArrayTemplate.h"
#include "PointTemplate.h"
using namespace std;

int main() {
	BoundCheckArray<Point<int>> oarr1(3);
	// Point<int> 템플릿 클래스의 객체를 저장할 수 있도록 
	oarr1[0] = Point<int>(3, 4);
	oarr1[1] = Point<int>(5, 6);
	oarr1[2] = Point<int>(7, 8);

	for (int i = 0; i < oarr1.GetArrLen(); i++) {
		oarr1[i].ShowPosition();
	}


	BoundCheckArray<Point<double>>oarr2(3);
	// Point<double> 템플릿 클래스의 객체를 저장할 수 있도록
	oarr2[0] = Point<double>(3.14, 4.31);
	oarr2[1] = Point<double>(5.09, 6.07);
	oarr2[2] = Point<double>(7.82, 8.54);

	for (int i = 0; i < oarr2.GetArrLen(); i++) {
		oarr2[i].ShowPosition();
	}


	typedef Point<int>* POINT_PTR;
	BoundCheckArray<POINT_PTR> oparr(3);
	// POINT_PTR (= Point<int>*) 템플릿 클래스의 객체를 저장할 수 있도록
	oparr[0] = new Point<int>(11, 12); // 주소값을 저장해야 하므로 동적할당 필요
	oparr[1] = new Point<int>(13, 14);
	oparr[2] = new Point<int>(15, 16);

	for (int i = 0; i < oparr.GetArrLen(); i++) {
		oparr[i]->ShowPosition(); 
		// oparr[i]는 주소값을 담고 있으므로 포인터로 요소를 선택하는 -> 필요
	}

	delete oparr[0]; delete oparr[1]; delete oparr[2];
	return 0;
}


1) Point 템플릿을 사용하지 않은 경우

BoundCheckArray<Point> arr(3);

2) Point 템플릿 사용한 경우

BoundCheckArray<Point<int>> oarr(3);

BoundCheckArray<Point<int>*> oparr(3);

 

 


2. 특정 템플릿 클래스의 객체를 인자로 받는 일반함수의 정의와, friend 선언

- 위와 같은 Point<int>, Point<double>과 같은 템플릿 클래스의 자료형을 대상으로도, 템플릿이 아닌 일반함수의 정의가 가능하다.

- 또한 클래스 템플릿 내에서 이러한 함수를 대상으로, friend 선언도 가능하다.

 

Case 2 )

#include <iostream>
using namespace std;

template <typename T>
class Point {
private:
	T xpos, ypos;
public:
	Point(T x = 0, T y = 0) :xpos(x), ypos(y) { }
	void ShowPosition() const {
		cout << '[' << xpos << ", " << ypos << ']' << endl;
	}
	/* Point<int> 객체의 +연산자를 오버로딩 하는 일반함수 (함수 템플릿 X)
    * cf) 함수 템플릿 특수화 : Point<int> operator+<Point<int>> 이런 식으로 이루어져야 함
    */
	friend Point<int>operator+(const Point<int>&, const Point<int>&);
	// Point<int> 템플릿 함수 사용한 객체, 이 객체끼리 operator+할 일이 있다면
	friend ostream& operator<<(ostream& os, const Point<int>& pos);
	// Point<int> 템플릿 함수를 사용한 객체가 cout을 할 일이 있다면
};

// Point<int> 템플릿 함수 사용한 객체, 이 객체끼리 operator+할 일이 있다면
Point<int> operator+(const Point<int>& pos1, const Point<int>& pos2) {
	return Point<int>(pos1.xpos + pos2.xpos, pos1.ypos + pos2.ypos);
}


// Point<int> 템플릿 함수를 사용한 객체가 cout을 할 일이 있다면
ostream& operator<<(ostream& os, const Point<int>& pos) {
	os << '[' << pos.xpos << ", " << pos.ypos << ']' << endl;
	return os;
}

int main() {
	Point<int> pos1(2, 4); // 템플릿 함수 사용해서 객체 생성
	Point<int> pos2(4, 8); 
	Point<int> pos3 = pos1 + pos2; // 특정<int> 템플릿 클래스의 객체로 인자를 받는 일반함수 실행
	cout << pos1 << pos2 << pos3;
	return 0;
}

 


[ 다른 게시물들을 더 보고싶다면? ]

2021.06.29 - [문과 코린이의, [C. C++] 기록/C++ 이론] - [문과 코린이의 IT 기록장] C,C++ - 템플릿(Template)에 대한 이해와 함수 템플릿 (함수를 대상으로 템플릿 이해하기, 함수 템플릿과 템플릿 함수, 둘 이상의 형(Type)에 대해 템플릿 선언하기, 함수 ..

 

[문과 코린이의 IT 기록장] C,C++ - 템플릿(Template)에 대한 이해와 함수 템플릿 (함수를 대상으로 템

[문과 코린이의 IT 기록장] C,C++ - 템플릿(Template)에 대한 이해와 함수 템플릿 (함수를 대상으로 템플릿 이해하기, 함수 템플릿과 템플릿 함수, 둘 이상의 형(Type)에 대해 템플릿 

vansoft1215.tistory.com

2021.06.29 - [문과 코린이의, [C. C++] 기록/C++ 이론] - [문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (클래스 템플릿의 정의, 클래스 템플릿의 선언과 정의의 분리, 배열 클래스의 템플릿화)

 

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (클래스 템플릿의 정의, 클래스 템플릿

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (클래스 템플릿의 정의, 클래스 템플릿의 선언과 정의의 분리, 배열 클래스의 템플릿화) 1. 클래스 템플릿의 정의 [문과

vansoft1215.tistory.com

 


* 유의사항
- 아직 공부하고 있는 문과생 코린이가, 정리해서 남겨놓은 정리 및 필기노트입니다.
- 정확하지 않거나, 틀린 점이 있을 수 있으니, 유의해서 봐주시면 감사하겠습니다.
- 혹시 잘못된 점을 발견하셨다면, 댓글로 친절하게 남겨주시면 감사하겠습니다 :)
반응형