타입의 새로운 별칭을 정의하는 키워드
typedef struct 구조체이름 {
자료형 멤버이름;
} 구조체별칭;
typedef는 클래스 안에서 타입의 새로운 별칭을 지을 수 있다.
class MyTypeClass
{
public:
typedef int Type1;
};
int main()
{
MyTypeClass a;
MyTypeClass::Type1 b;
return 0;
}
a는 MyTypeClass의 객체, b는 int 변수이다.
class MyTypeClass
{
public:
typedef int Type1;
private:
typedef double Type2;
};
int main()
{
MyTypeClass a;
MyTypeClass::Type1 b;
MyTypeClass::Type2 c; //에러
return 0;
}
타입선언이 private로 선언되어 있으면 사용하는 것도 내부적으로 사용해야함.
->typedef은 클래스 안에서도 타입의 별칭을 만들 수 있을 뿐 아니라 외부접근 제한 까지 영향을 받는다.
템플릿 파라미터로 받은 데이터 타입이 필요할 때
#include <iostream>
template<typename T>
class MyTempClass
{
public:
typedef T TempType;
};
int main()
{
MyTempClass<int> a;
MyTempClass<int>::TempType b;
MyTempClass<double> c;
MyTempClass<double>::TempType d;
return 0;
}
타입 안 타입의 객체를 호출 할 수 있다. 이렇게 템플릿 매개변수에 종속된 것을 의존 이름(dependent name) 이라고 한다. 클래스안에 중첩된 경우가 있는데 중첩 의존 이름(nested dependent name) 이라고 한다.
ex) STL의 반복자 (C++ Standard Library 예제)
컨테이너를 받아서 처음부터 끝까지 루프 돌며 모든 원소를 출력하는 코드.
template <class T>
inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="")
{
typename T::const_iterator pos;
// typename 키워드는 다음에 언급합니다
std::cout << optcstr;
for (pos=coll.begin(); pos!=coll.end(); ++pos) {
std::cout << *pos << ' ';
}
std::cout << std::endl;
}
컨테이너가 벡터, 리스트, 데크 인지도 알 수 없지만 컨테이너 원소가 int, double, char 형인지 도 알 수 없다. 하지만 각 컨테이너 안에 상수반복자를 typedef 키워드로 const_iterator 라고 정의 했기에 어떤 원소를 담은 어떤 컨테이너가 들어와도 함수가 동작 할 수 있다.
+typedef 이름 관례: typedef로 새로운 이름을 만들 떄 원래 그 멤버 이름과 똑같이 짓는 것이 관례이다.
int x;
int y;
y = x * 3; //문제는 없다.
typedef int Inches;
typedef int Dollars;
Inches x;
Dollars y;
y = x * 3; //의사 전달이 쉽다.
#if defined USING_COMPILER_A
typedef __int32 Int32;
typedef __int64 Int64;
#elif deined USING_COMPILER_B
typedef int Int32;
typedef long long Int64;
#endif
ex) 잘못된 코드
template <typename T>
class MyTypeClass
{
public:
typedef T A;
static int B;
class C{};
static void D( void ){}
};
void foo()
{
...
MyTypeClass<int>::A *E; //1번 = 하위 타입인 A의 포인터 변수 E를 선언
MyTypeClass<int>::B *F; //2번 = 정적 변수 B와 변수 F를 곱셈하는 코드
MyTypeClass<int>::C *G; //3번 = 하위 클래스 C의 포인트 변수 G를 선언
MyTypeClass<int>::D *H; //4번 = 정적 함수 D와 변수 H를 곱셈하는 코드
}
코드 타입이 똑같다. 그렇기 때문에 c++에서는 'A는 타입이야' 라고 알려주기 위해 typename을 사용한다.
void foo()
{
...
typename MyTypeClass<int>::A *C; //1번
MyTypeClass<int>::B *D; //2번
}