소년코딩

05.06 - typedef

typdef를 사용하면 프로그래머가 타입의 별칭을 생성하고, 실제 타입 이름 대신 별칭을 사용할 수 있다. 즉, C++에서 이미 정의된 자료형이나 사용자 정의 자료형보다 더 짧거나 의미 있는 이름을 지어줄 수 있다. typedef를 선언하려면 typedef 키워드를 사용하고 자료형 다음에 별칭 이름을 사용하면 된다.

typedef double distance_t; // distance_t을 double 자료형의 별칭으로 정의한다.

// 다음 두 문장은 같다.
double howFar;
distance_t howFar;

관습적으로 typedef 별칭은 "_t" 접미사를 사용하여 선언한다.

typdef는 새로운 타입을 정의하지 않는다. 기존 타입의 별칭일 뿐이다. tydef는 일반 타입을 사용할 수 있는 곳이라면 어디서든 사용할 수 있다.

typedef long miles_t;
typedef long speed_t;

miles_t distance = 5;
speed_t mhz = 3200;

// miles_t와 speed_t는 실제로 long 타입이기 때문에, 아래 코드는 유효하다.
distance = mhz;

typedef는 다양한 상황에서 유용하다.

가독성을 위해 typedef 사용하기 (Using typedefs for legibility)

가독성을 위해 typedef를 사용할 수가 있다. char, int, long, float, doublebool과 같은 자료형의 이름은 함수가 반환하는 자료형을 설명하는 데 유용하지만, 반환 값의 목적을 알고 싶은 경우가 많다.

int GradeTest();

반환 값은 정수이지만 정수에 대한 정확한 의미는 알 수 없다. int는 아무 말도 하지 않는다.

typedef int testScore_t;
testScore_t GradeTest();

그러나 testScore_t 반환 타입을 사용하면, 함수가 테스트 점수를 나타내는 타입을 반환한다는 것을 알 수 있다.

플랫폼 독립 코딩

typdef의 가장 큰 장점은 플랫폼 특정 세부 사항을 숨기는 데 사용할 수 있다는 것이다. 플랫폼에 따라서, 정수는 2바이트 또는 4바이트다. 따라서 int를 사용해 2바이트가 넘는 정보를 저장하는 것은 잠재적으로 위험할 수 있다.

char, short, intlong은 해당 크기를 나타내지 않으므로 교차 플랫폼(cross-flatform) 프로그램에서 크기(비트)를 나타내는 별칭을 정의하는 것이 매우 일반적이다. 예를 들어 int8_t는 8비트 부호 있는 정수, int16_t는 16비트 부호 있는 정수, int32_t는 16비트 부호 있는 정수다. 이러한 방식으로 typedef를 사용하면 실수를 방지하고 변수의 크기에 대해 더욱 명확히 알 수 있다.

일반적으로 typedef를 전처리기와 같이 사용해서 올바른 크기로 해석하게 한다.

#ifdef INT_2_BYTES
typedef char int8_t;
typedef int int16_t;
typedef long int32_t;
#else
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
#endif

복잡한 타입을 간단하게 만들기 (Using typedefs to make complex types simple)

지금까지 단순한 데이터 타입만 처리했지만, C++에는 다음과 같이 선언된 변수와 함수를 볼 수 있다.

std::vector<std::pair<std::string, int>> pairlist;

bool hasDuplicates(std::vector<std::pair<std::string, int> > pairlist)
{
    // some code here
}

매번 std::vector<std::pair<std::string, int>>를 입력하는 건 성가시고 어렵다. 이럴 때 typedef를 사용하면 훨씬 쉬어진다.

typedef std::vector<std::pair<std::string, int>> pairlist_t; // make pairlist_t an alias for this crazy type

pairlist_t pairlist; // instantiate a pairlist_t

bool hasDuplicates(pairlist_t pairlist) // use pairlist_t in a function parameter
{
    // some code here
}

훨씬 낫다! 이제 std::vector<std::pair<std::string, int>> 대신에 pairlist_t만 입력하면 된다.

std::vectorstd::pair를 모르더라도 걱정하지 말자. 나중에 다룰 예정이다.


Type aliases in C++11

typedef에는 몇 가지 이슈가 있다.

첫째, 타입 이름이나 타입 정의가 먼저 온다는 사실을 잊기 쉽다.

typedef distance_t double; // incorrect
typedef double distance_t; // correct

둘째, typedef 문법은 복잡한 타입일수록 더 못생기게 변한다.

C++ 11에서는 이러한 이슈를 해결하기 위해 새로운 typedef 문법을 도입했다. 이 문법을 타입 별칭(type alias)이라고 한다.

typedef를 사용하면:
typedef double distance_t; // define distance_t as an alias for type double
C++ 11에서는 다음과 같이 선언할 수 있다:
using distance_t = double; // define distance_t as an alias for type double

위 둘은 기능적으로 같다.

C++ 11은 using 키워드를 사용하는데, 여기서 이는 오버로드(overload)된 의미이며 네임스페이스와 아무런 관련이 없다.


cpp 번역: 이 포스트의 원문은 http://www.learncpp.com/cpp-tutorial/46-typedefs-and-type-aliases/ 입니다.

'C++ 이야기 > 05. 다양한 타입' 카테고리의 다른 글

C++ 05.08 - auto  (0) 2018.07.08
C++ 05.07 - 구조체, struct  (1) 2018.07.07
C++ 05.05 - enum class  (1) 2018.07.04
C++ 05.04 - 열거형, enum  (3) 2018.07.03
C++ 05.03 - 문자열, std::string  (1) 2018.07.03
댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기