개발/C++

[C++] Empty Class란?

재근이 2021. 10. 8. 10:51
반응형

💡목표

Empty Class 특징에 대해서 알아보고, 어떠한 것들이 Empty Class를 말하는지 예시를 통해서 알아보자.

 

🔦Empty Class 특징

  • size가 1byte
  • (non-static) member 변수없다.
  • 가상 함수없다.
  • 가상 상속을 하지 않는다.
  • class또는 struct를 말하며, union은 Empty Class가 될 수 없다.

 

🔮Empty Class 확인 방법

type_traits 헤더 파일에 있는 is_empty_v를 통해서 Empty를 판별할 수있다.

C++1117에서 사용법이 다르니 확인해서 사용해야한다.

/* 헤더 */
#include <type_traits>

/* C++11 */
std::is_empty_v<type>::value

/* C++17 */
std::is_empty_v<type>

 

📝Empty Class 판별 예시

특징에 대해 설명을 듣는 것보다 실제 예시를 통해서 확인하는 게 이해하기 좋다.

실제 어떠한 것들이 Empty Class를 말하는 건지 실제 코드를 보면서 이해해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <type_traits>    // is_empty_v
#include <functional>    // plus, modulus
 
class O_Empty_1 {};    // Empty
class O_Empty_2 {
    static int sData;    // 멤버 변수가 아님
public:
    O_Empty_2() {};
    void func() {}
};
class O_Empty_3 : public O_Empty_2 {};    // Empty 클래스를 상속하고 있어 Empty
 
class X_Empty_1 {        // 멤버 변수가 있어 Empty가 아님
    int memData;
};
class X_Empty_2 {
    virtual void func() {}    // 가상 함수가 있어 Empty가 아님
};
class X_Empty_3 : public X_Empty_2 {};    // Empty가 아닌 클래스를 상속하고 있어 Empty가 아님
class X_Empty_4 : virtual public O_Empty {};    // 가상 상속하고 있어 Empty가 아님
class X_Empty_5 {
    O_Empty_1 e;    // Empty 객체라도 멤버 변수 이기에 Empty가 아님
};
 
int main()
{
    /* Empty Class 크기 */
    std::cout << sizeof(O_Empty) << std::endl;    // 1
    std::cout << sizeof(X_Empty) << std::endl;    // 4
 
    /* 출력을 true/false로 */
    std::cout << std::boolalpha;
 
    std::cout << std::is_empty<O_Empty_1>::value << std::endl;    // true
    std::cout << std::is_empty<O_Empty_2>::value << std::endl;    // true
    std::cout << std::is_empty<O_Empty_3>::value << std::endl;    // true
 
    std::cout << std::is_empty<X_Empty_1>::value << std::endl;    // false
    std::cout << std::is_empty<X_Empty_2>::value << std::endl;    // false
    std::cout << std::is_empty<X_Empty_3>::value << std::endl;    // false
    std::cout << std::is_empty<X_Empty_4>::value << std::endl;    // false
    std::cout << std::is_empty<X_Empty_5>::value << std::endl;    // false
 
    /* 함수 객체 */
    std::plus<int> p;
    std::modulus<int> m;
 
    std::cout << std::is_empty<decltype(p)>::value << std::endl;    // true
    std::cout << std::is_empty<decltype(m)>::value << std::endl;    // true
 
    /* 람다 */
    int cap;
    auto l1 = [](int a) { return a*10; };        //캡처 안한 람다
    auto l2 = [cap](int a) { return a*10; };    //캡처 한 람다
 
    std::cout << std::is_empty<decltype(l1)>::value << std::endl;    // true
    std::cout << std::is_empty<decltype(l2)>::value << std::endl;    // false
 
    /* allocator */
    std::allocator<int> al;
    std::cout << std::is_empty<decltype(al)>::value << std::endl;    // true
 
    return 0;
}
cs
반응형