[C++ Core] POD(plain old data), 표준 레이아웃 타입(standard layout type), 간단한 타입(trivial type)
POD
POD(plain old data)란, 메모리 상에서 연속적인 바이트 열을 말한다. 이따금씩 개체를 POD로 취급해야 할 때가 있다. 가령 실행 시간 다형성이나 유저가 정의한 복사 의미론 등과 같은 진보된 의미론 문법이 필요없을 때말이다. 왜냐하면, POD로 취급하면 하드웨어에서 좀 더 효율적으로 개체를 옮기거나 복사할 수 있기 때문이다. 즉, POD는 클래스 레이아웃이나 유저가 정의한 생성, 복사, 이동 의미론의 복잡성에 대한 고려 없이 '데이터 자체'로 취급할 수 있는 개체이다.
POD 개체는 다음 조건을 갖춰야 한다.
- 표준 레이아웃 타입(standard layout type)이어야 한다.
- 간단한 타입(trivial type)이어야 한다.
우선 저것들이 의미하는 게 무엇인지 살펴보자.
표준 레이아웃 타입
기본적으로, 표준 레이아웃 타입(standard layout type)은 C와 분명하게 같은 레이아웃을 갖고 있는 타입이며, 공통 C++ ABIs(Apllication Binary Interfaces)가 다룰 수 있는 타입이다.
자세하게는 다음의 특성을 가진다.
- 가상 함수나 가상 기저 클래스를 갖지 않는다.
- 비정적 데이터 멤버가 동일한 접근 제어를 가진다.
- 모든 비정적 데이터 멤버가 표준 레이아웃이다.
- 모든 기저 클래스가 표준 레이아웃이다.
- 첫번째 비정적 멤버로 기저 클래스와 동일한 타입의 데이터를 갖지 않는다.
- 레퍼런스 멤버를 갖지 않는다.
- 한 개 이상의 기저 클래스 혹은 파생 및 기저 클래스 둘 다에서 비정적 데이터를 갖지 않는다.
좀 더 간단하게 살펴보려면 <type_traits>
의 std::is_standard_layout
을 이용하면 된다.
간단한 타입
간단한 타입(trivial type)은 (1)간단한 기본 생성자 및 소멸자와 (2)간단한 복사 및 이동 연산을 갖고 있는 타입이다. 다르게 말하면, 비트 단위 연산들이 가능하면 된다.
복사, 이동, 소멸자가 간단하지 않은 경우는 다음과 같다.
- 유저가 정의한 것이다.
- 그 클래스가 가상 함수를 가진다.
- 그 클래스가 가상 기저 클래스를 가진다.
- 그 클래스가 간단하지 않은 멤버나 기저 클래스를 가진다.
위와 마찬가지로 <type_traits>
의 std::is_trivial
을 이용하면 쉽게 확인할 수 있다.
참고로 내장 타입 개체는 표준 레이아웃을 가지며, 간단한 타입이다. 물론, 이런 타입들의 배열도 마찬가지이다.
다시 POD
POD가 될 수 있는 조건을 좀 더 쉽게 풀어보자.
- 복잡한 레이아웃을 갖지 않는다.(가상 함수 등)
- 유저가 정의한 복사 의미론을 갖지 않는다.
- 간단한 기본 생성자를 갖고 있다.
또한, C++11부터는 기본이 아닌 생성자를 추가하거나 빼는 것이 레이아웃이나 성능에 영향을 주지 않는다.
예시를 보자.
struct S0 { }; // POD struct S1 { int i; }; // POD struct S2 { int i; S2(int ii) : i(ii) { } }; // 기본 생성자가 없으므로 POD가 아니다 struct S3 { int i; S3(int ii) : i(ii) { } S3() {} }; // POD struct S4 { int i; S4(int ii) : i(ii) { } S4() = default; }; // POD struct S5 { virtual void f(); }; // 가상 함수가 있으므로 POD가 아니다 struct S6 : S1 { }; // POD struct S7 : S0 { int b; } // POD struct S8 : S1 { int b; } // 기저 클래스에 비정적 멤버가 있으므로 POD가 아니다. struct S9 : S0, S1 { }; // POD
마찬가지로 <type_traits>
의 std::is_pod
를 이용하면 쉽게 알 수 있다.
'Outdated > Core Language' 카테고리의 다른 글
[C++ Core] 함수 개체(function object)와 람다 표현식(lambda expression) (0) | 2018.09.07 |
---|---|
[C++ Core] 상수 구문 - new 연산자 (0) | 2018.08.29 |
[C++ Core] 상수 구문 - const vs constexpr (0) | 2018.08.21 |
[C++ Core] 우측 값 레퍼런스(rvalue reference) (4) | 2018.08.15 |
[C++ Core] 타입 추론(type deduction) - auto와 decltype (0) | 2018.08.13 |