for Robot Artificial Inteligence

16. Static-Variables-and-Functions

|

(Static-Variables-and-Functions)[https://ju3un.github.io/global-static/]

  • 프로그래밍을 처음 배울 때 우리는 지역 변수, 전역 변수라는 용어를 흔히 들을 수 있다.
  • 지역 변수는 말그대로 정의되는 시점에서 생성되고 초기화되며, 정의된 스코프(블록)이 끝나는 지점에서 소멸한다.
  • 그렇다면 전역 변수는 이름 그대로 지역 변수와는 반대로 전역에서 사용할 수 있다고 추측할 수 있다

전역 변수(Global Variable)와 정적 변수(Static Variable)

  • 이 둘의 공통점은 지역 변수와는 다르게 프로그램이 끝날 때 비로소 소멸된다는 것을 알고 있다

1. 전역 변수(Global Variable)

  • 한 번 할당된 변수의 메모리와 값은 프로그램이 종료될 때까지 유지된다. (=lifetime 프로그램 종료시.)
  • 해당 프로그램의 어느 파일, 함수에서도 접근 가능하다
  • 다른 파일에서 접근하기 위해서는 아래와 같이 extern 키워드를 사용하여 변수를 선언하고 사용해야 한다
  • 필요할 때 초기화를 언제든 몇번이든 할 수 있다.
  • 초기화를 하지 않아도 메모리가 할당된다. (초기화 시 data영역에 존재)
int g_iValue;           // 본문 선언
extern int g_iValue;    // 다른 파일에서 선언 후 사용

2. 전역 변수(Static Variable)

  • 한 번 할당된 변수의 메모리와 값은 프로그램이 종료될 때까지 유지된다. (=lifetime 프로그램 종료시.)
  • 해당 변수가 선언된 파일, 함수내에서만 접근 가능하다.
  • 선언 시 static 키워드를 반드시 사용해야 한다.
  • 초기화는 단 한번만 할 수 있으며 초기화는 반드시 소스 파일 에서 해야 한다.
  • 본문 / 다른 파일 사용 방법은 없음(x)
  • 초기화하지 않은 상태로 어느 곳에서도 사용되지 않으면 메모리가 할당되지 않는다. (초기화 시 data영역에 존재)
static int s_iValue;    // 본문 선언
  • 해당 클래스의 모든 인스턴스들의 공통적인 공유 자원(해당 클래스가 여러 개의 객체가 생성되어도 해당 변수는 단 한번만 생성되고 초기화된다.)
  • 객체가 생성되기 전에 이미 메모리가 할당되어, 생성자에서 초기화해줄 수 없다.
  • 각 인스턴스의 귀속 값이 아니기 때문에 호출 시, 클래스명을 명시하여 호출하는 것이 올바르다.
  • C++에서 정적 멤버란 클래스에는 속하지만, 객체 별로 할당되지 않고 클래스의 모든 객체가 공유하는 멤버를 의미합니다.
  • 멤버 변수가 정적(static)으로 선언되면, 해당 클래스의 모든 객체에 대해 하나의 데이터만이 유지 관리됩니다.
  • 정적 멤버 변수는 클래스 영역에서 선언되지만, 정의는 파일 영역에서 수행됩니다.
  • 이러한 정적 멤버 변수는 외부 연결(external linkage)을 가지므로, 여러 파일에서 접근할 수 있습니다
  • 정적 멤버 변수에도 클래스 멤버의 접근 제한 규칙이 적용되므로, 클래스의 멤버 함수나 프렌드만이 접근할 수 있습니다.
  • 하지만 정적 멤버 변수를 외부에서도 접근할 수 있게 하고 싶으면, 정적 멤버 변수를 public 영역에 선언하면 됩니다.
this.m_iValue   // (x)
Price::m_iValue // (o) 올바른 표현

예제

class Person

{

private:

    string name_;

    int age_;

public:

    static int person_count_;            // 정적 멤버 변수의 선언

    Person(const string& name, int age); // 생성자

    ~Person() { person_count_--; }       // 소멸자

    void ShowPersonInfo();

};  

...

int Person::person_count_ = 0; // 정적 멤버 변수의 정의 및 초기화

실행 결과

1 번째 사람이 생성되었습니다.

이 사람의 이름은 길동이고, 나이는 29살입니다.

2 번째 사람이 생성되었습니다.

이 사람의 이름은 순신이고, 나이는 35살입니다.

(정적 함수)[http://tcpschool.com/cpp/cpp_encapsulation_staticConst]

  • C++에서는 클래스의 멤버 함수도 정적(static)으로 선언할 수 있습니다.
  • 이렇게 선언된 정적 멤버 함수는 해당 클래스의 객체를 생성하지 않고도, 클래스 이름만으로 호출할 수 있습니다.
  • 정적 멤버 함수는 정적 멤버 변수를 선언하는 방법과 같이 static 키워드를 사용하여 선언합니다.
  • 이러한 정적 멤버 함수는 다음과 같은 특징을 갖습니다.
    1. 객체를 생성하지 않고 클래스 이름만으로 호출할 수 있습니다.
    2. 객체를 생성하지 않으므로, this 포인터를 가지지 않습니다
    3. 특정 객체와 결합하지 않으므로, 정적 멤버 변수밖에 사용할 수 없습니다.

예제

class Person

{

private:

    string name_;

    int age_;

public:

    static int person_count_;            // 정적 멤버 변수의 선언

    static int person_count();           // 정적 멤버 함수의 선언

    Person(const string& name, int age); // 생성자

    ~Person() { person_count_--; }       // 소멸자

    void ShowPersonInfo();

};

...

int Person::person_count_ = 0; // 정적 멤버 변수의 정의 및 초기화

...

int Person::person_count()     // 정적 멤버 함수의 정의

{

    return person_count_;

}

실행 결과

1 번째 사람이 생성되었습니다.

2 번째 사람이 생성되었습니다.

현재까지 생성된 총 인원 수는 2명입니다.

Exercise

Main.cpp

#include <iostream>
#include "user.h"

using namespace std;
/*static properties and static methods */

int main()
{


    cout << User::getCounter() << endl;

    return 0;
}

user.h

#ifndef USER_H_INCLUDED
#define USER_H_INCLUDED

class User
{
        int ID;
        static int counter;
    public:
        User();
        ~User();
        int getID() { return ID; }
        static int getCounter() { return counter; }
};

#endif // USER_H_INCLUDED

farm.cpp

#include "user.h"

int User::counter = 0;

User::User()
{
    counter++;
    ID = counter;
}
User::~User()
{

}


Comments