codenuri 강석민 강사 강의 내용기반으로 정리한 내용입니다.
class template
- 템플릿과 타입
- Complex : template
- Complex
: type
- 멤버함수 안에서는 Complex
대신 Complex를 사용할 수 있다.
template<typename T> class Complex
{
T re, im;
public:
void foo(Complex c) // void foo(Complex<T> c)
{
Complex c2; // Complex<T> c2;
}
};
/*
void foo(Complex c) // error (타입이 아니므로)
{
}
*/
int main()
{
Complex c1; // error
Complex<int> c2; // ok.
}
- 디폴트 값 표기
- int a = 0;
- T a = T(); // C++98
- T a = {}; // C++11
멤버 함수를 외부에 구현하는 모양
static member data 의 외부 선언
- 클래스 템플릿의 멤버 함수 템플릿
template<typename T> class Complex
{
T re, im;
public:
// 1
Complex(T a= {}, T b= {}) : re(a), im(b) {}
T getReal() const;
static int cnt;
template<typename U> T func(const U& c);
};
// 2
template<typename T> T Complex<T>::getReal() const
{
return re;
}
// 3
template<typename T> int Complex<T>::cnt = 0;
// 4
template<typename T> template<typename U>
T Complex<T>::func(const U& c)
{
}
int main()
{
}
generic copy constructor
template<typename T> class Complex
{
T re, im;
public:
Complex(T a= {}, T b= {}) : re(a), im(b) {}
};
int main()
{
Complex<int> c1(1, 1); // ok
Complex<int> c2 = c1; // ok
Complex<double> c3 = c1; // ?? Complex<int> 와 Complex<double>은 다른 타입
// -> 복사 생성자는 같은 타입으로 초기화 될 때 사용된다.
}
위의 코드 문제점 해결하기 위해 복사생성자를 만든다.
template<typename T> class Complex
{
T re, im;
public:
Complex(T a= {}, T b= {}) : re(a), im(b) {}
// 일반적인 복사 생성자. -> 자신과 동일한 타입만 인자로 받을 수 있다.
// Complex(const Complex<T>& c) {}
// Complex int 가 넘어갈 수 있어 컴파일 시 error 가 안남 -> 단, Complex<int> 만 인자로 받을 수 있다.
// Complex(const Complex<int>& c) {}
// Complex<모든 타입> 을 인자로 받을 수 있다 -> 일반화된 복사생성자
template<typename U>
Complex(const Complex<U>& c) {}
};
int main()
{
Complex<int> c1(1, 1);
Complex<int> c2 = c1;
Complex<double> c3 = c1; // error
}
복사생성자 구현
template<typename T> class Complex
{
T re, im;
public:
Complex(T a= {}, T b= {}) : re(a), im(b) {}
// 일반화된 복사 생성자
template<typename U>
Complex(const Complex<U>& c) {}
template<typename> friend class Complex;
};
template<typename T> template<typename U>
Complex<T>::Complex(const Complex<U>& c) : re(c.re), im(c.im)
// 컴파일 시 private error 발생(int 와 double은 다른 것이므로 friend 처리 필요
{
}
int main()
{
Complex<int> c1(1, 1);
Complex<int> c2 = c1;
Complex<double> c3 = c1; // error
}
일반화된 복사생성자
클래스 템플릿의 멤버함수 템플릿으로 구현하는 복사 생성자
U(int)가 T(double)로 복사(대입) 가능하다 면 Complex 도 Complex
에 복사(대입) 가능해야한다. friend class 로 선언되어야 한다.
#include <memory>
using namespace std;
class Animal {};
class Dog: public Animal {};
int main()
{
shared_ptr<Dog> p1(new Dog);
shared_ptr<Animal> p2 = p1;
p2 = p1;
if (p2 == p1) {}
if (p2 != p1) {}
}
shared_ptr 모두 템플릿으로 되어 있어 위와 같이 사용 가능함