12.13 Static member variables

주홍영·2022년 3월 17일
0

Learncpp.com

목록 보기
137/199

https://www.learncpp.com/cpp-tutorial/static-member-variables/

우리는 static variable이 scope 밖을 벗어나더라도 값이 유지되고 소멸하지 않는 것을 배웠다

example:

#include <iostream>

int generateID()
{
    static int s_id{ 0 };
    return ++s_id;
}

int main()
{
    std::cout << generateID() << '\n';
    std::cout << generateID() << '\n';
    std::cout << generateID() << '\n';

    return 0;
}

위 프로그램의 출력은 다음과 같다

1
2
3

만약 static keyword가 global variable에 적용되면 의미가 달라진다
이때에는 internal linkage 속성을 부여한다
internal linkage란 file 밖에서 variable이 접근되는 것을 제한하는 것이다
보통 global variable은 사용이 지양되므로 static keyword는 이런 케이스에서
자주 사용되지는 않는다

Static member variables

c++은 class에서 static의 두가지 용법을 제공하고 있다
하나는 static member variable이고
또 하나는 static member function이다

example:

class Something
{
public:
    static int s_value;
};

int Something::s_value{ 1 };

int main()
{
    Something first;
    Something second;

    first.s_value = 2;

    std::cout << first.s_value << '\n';
    std::cout << second.s_value << '\n';
    return 0;
}

위 코드의 출력은

2
2

first와 second모두 서로 다른 object 이지만 static member variable을 공유하므로
위와 같은 출력이 나온 것이다

Static members are not associated with class objects

static member variable은 object랑 상관없이 프로그램이 시작함과 동시에
instantiate 된다고 생각하면된다

결론적으로 static member variable은 object가 아닌 클래스 그 자체에 속한다고 보면 된다

그래서 static member variable은 object를 거치지 않고 direct로 접근할 수 있다

class Something
{
public:
    static int s_value; // declares the static member variable
};

int Something::s_value{ 1 }; // defines the static member variable (we'll discuss this section below)

int main()
{
    // note: we're not instantiating any objects of type Something

    Something::s_value = 2;
    std::cout << Something::s_value << '\n';
    return 0;
}

위에서 Something::s_value 와 같이 클래스의 이름으로 direct 접근이 가능하다

Defining and initializing static member variables

만약 클래스 내부에서 initialize 하지 않았으면 (forward declaration만 한 경우)
함수 정의하는 방식처럼 클래스 밖에서 initialize를 해줘야 한다

int Something::s_value{ 1 }; // defines the static member variable

흡사 함수를 define하는 것과 비슷하다

Inline initialization of static member variables

외부에서 define 하는 것 말고 클래스 내부에서 initialization도 가능하다
만약 const variable인 경우 클래스 내부에서 declaration과 동시에 init하면 된다

class Whatever
{
public:
    static const int s_value{ 4 }; // a static const int can be declared and initialized directly
};

그리고 c++17의 경우 non-const static member variable의 경우
inline 키워드를 이용해서 class 내부에서 init을 할 수 있다

class Whatever
{
public:
    static inline int s_value{ 4 }; // a static inline int can be declared and initialized directly (C++17)
};

example

#include <iostream>

class Something
{
private:
    static inline int s_idGenerator { 1 }; // C++17
//  static int s_idGenerator;              // Use this instead for C++14 or older
    int m_id { };

public:
    Something()
    : m_id { s_idGenerator++ } // grab the next value from the id generator
    {}

    int getID() const { return m_id; }
};

// For C++14 or older, we have to initialize the non-const static member outside the class definition
// Note that we're defining and initializing s_idGenerator even though it is declared as private above.
// This is okay since the definition isn't subject to access controls.
// int Something::s_idGenerator { 1 }; // start our ID generator with value 1 (uncomment for C++14 or older)

int main()
{
    Something first;
    Something second;
    Something third;

    std::cout << first.getID() << '\n';
    std::cout << second.getID() << '\n';
    std::cout << third.getID() << '\n';
    return 0;
}

init list로 constructor에서 m_id를 초기화 하고 있는데
postfix increment operator가 사용되었으므로
현재 값을 할당하고 +1을 한다
따라서 first에서 m_id는 1, second에서는 2, third에서는 3이 할당된다
그러므로 위 프로그램의 출력은 다음과 같다

1
2
3

profile
청룡동거주민

0개의 댓글