
Udemy에서 C++ 언 매니지드 프로그래밍을 수강하면서 배운 내용을 정리한 것입니다.
Static 키워드
- 범위(scope)의 제한을 받는 전역 변수 : 실행 도중 딱 하나만 존재하는 변수, 단 접근이 제한됨.
- 제한되는 범위는?
- 파일 속
- 네임스페이스 속
- 클래스 속
- 함수 속
- static 혐오론자들이 존재하기는 함 OOP에 어울리지 않는다고 생각하는 분들.
- C++는 코드를 소스 파일 단위로 컴파일해서 나온 오브젝트 파일들을 링크 단계에서 서로 연결한다. 소스 코드 파일마다 정의된 이름은 외부 링크나 내부 링크를 통해 서로 연결된다.
- 외부 링크로 연결되면 다른 소스 파일에서 이름을 사용할 수 있다.
- 함수나 전역 변수는 기본적으로 외부 링크가 적용된다.
- 내부 링크(정적 링크)로 연결되면 같은 파일에서만 사용할 수 있다.
- static 키워드를 붙이면 내부 링크가 적용된다.
Static 변수가 하드웨어 메모리 상에서 딱 하나 존재한다는 것을 명심하자
Extern 키워드
- 다른 파일의 전역변수에 접근을 가능케 해 줌
- static과 정반대로 외부 링크를 지정할 때 사용.
함수 속 정적 변수
#include <iostream>
void Accumulate(int number)
{
static int result = 0;
result += number;
std::cout << "result = " << result << std::endl;
}
int main()
{
Accumulate(10); // print out 10
Accumulate(20); // print out 20
return 0;
}
보톰 함수에서 변수를 선언하면 스택에 메모리공간을 할당받고, 함수가 종료하면 스택에서 차례대로 변수를 반환한다.
static int result 변수를 짱 박혀 있음.
위의 함수의 작동로직을 설명하면 다음과 같다.
- Accumulate(10)이 호출
- static int result는 아직 초기화가 안되었다. 0으로 값을 초기화해 준다,
- result의 0에 10을 더해준다. (result == 10)
- result = 10이라고 출력
- Accumulate(20)이 호출
- (static int result는 이미 초기화가 되었기에 호출 않음 값은 여전히 10) result 10에 20을 더해준다. (result == 30)
- result = 30이라고 출력
- result 정적 변수는 오로지 함수로 범위(scope)가 제한된다.
- main문에서는 죽었다 깨어나도 result에 접근이 불가하다.
NOTE static 변수를 따로 만들어서 상태를 관리하지 말고, 상태를 객체 안에서 관리하게 만드는 게 좋다.
class 속 정적 멤버 변수
- 각 클래스당 하나의 copy만 존재
- 개체의 메모리 레이아웃의 일부가 아님
- 클래스 메모리 레이아웃에 포함
- exe파일 안에 필요한 메모리가 잡혀 있음
- 컴파일러가 이 변수의 인스턴스가 몇 개 존재해야 하는지 알고 있다. Only ONE
어떻게 실전에서 사용할 것인가
- 함수 안에서 정적 변수를 넣지 말 것
- 클래스 안에 넣을 것
- 전역변수 대신 정적 멤버변수를 쓸 것
- scope를 제한하기 위해
- C스타일의 정적 변수를 쓸 이유가 없음 -> OOP로 할 때는 굳이 할 필요가 없기는 한데, 현업에서는 여전히 쓰는 경우 있다.
정적 멤버 함수
- 논리적인 범위에 제한된 전역 함수
- 해당 클래스의 정적 멤버에만 접근 가능
- 개체의 멤버변수에는 접근 불가
- 개체가 없이도 정적 함수를 호출할 수 있음
- Math::Square(10);
정적 멤버 함수 예시)
sample_math.h
#pragma once
#incldue <cmath>
namespace samples
{
class Math
{
public:
static int Ceil(float value);
static int Floor(float value);
static float Power(float value, float power);
static int Round(float value);
static float Square(float value);
/*누군가가 Math의 객체를 만들기를 원하는 클래스가 아니다.
생성자를 private에 넣어주면 방지가능*/
private:
Math() {};
};
}
sample_math.cpp
#include "sample_math.h"
namespace samples
{
// 올림 함수
int Math::Ceil(float value)
{
int intValue = static_cast<int>(value);
if (value == static_cast<float>(intValue))
{
return intValue;
}
return intValue + 1;
}
//내림 함수
int Floor(float value)
{
return static_cast<int>(value);
}
//멱급수 함수
float Power(float value, float power)
{
return pow(value, power);
}
//반올림 함수 무조건 내림을 하되 0.5만큼 올리고 소숫점을 제거
int Round(float value)
{
return static_cast<int>(value + 0.5f);
}
float Square(float value)
{
return value * value;
}
}
반복 사용에 용이하고, 메모리 공간을 여러 번 할당 받지 않아도 되는 정적 멤버 함수를 가진 Class가 완성되었다.
'C++ > Unmanaged C++ 강좌 노트' 카테고리의 다른 글
[C++]인라인 함수 (0) | 2023.03.04 |
---|---|
[C++]파일 입출력(I/O) (4) | 2023.03.01 |
[C++]std::string C++의 신 기능은 항상 우월한가? (0) | 2023.03.01 |
[C++]bool과 참조 C++ 새로운 기능 (2) | 2023.03.01 |