16. Static-Variables-and-Functions
16 Sep 2019 | C++
(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 키워드를 사용하여 선언합니다.
- 이러한 정적 멤버 함수는 다음과 같은 특징을 갖습니다.
- 객체를 생성하지 않고 클래스 이름만으로 호출할 수 있습니다.
- 객체를 생성하지 않으므로, this 포인터를 가지지 않습니다
- 특정 객체와 결합하지 않으므로, 정적 멤버 변수밖에 사용할 수 없습니다.
예제
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()
{
}
(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 키워드를 사용하여 선언합니다.
- 이러한 정적 멤버 함수는 다음과 같은 특징을 갖습니다.
- 객체를 생성하지 않고 클래스 이름만으로 호출할 수 있습니다.
- 객체를 생성하지 않으므로, this 포인터를 가지지 않습니다
- 특정 객체와 결합하지 않으므로, 정적 멤버 변수밖에 사용할 수 없습니다.
예제
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