C++의 저장 클래스
안녕하세요, 열정적인 프로그래머 여러분! 오늘 우리는 C++ 저장 클래스의 세계를 함께 탐험해보겠습니다. 프로그래밍 초보자라도 걱정하지 마세요; 친절한 안내자로서 저가 단계별로 설명해드릴 테니까요. 시작해보겠습니다!
저장 클래스는 무엇인가요?
구체적인 내용에 들어가기 전에, 저장 클래스가 무엇인지 이해해보겠습니다. C++에서 저장 클래스는 변수와 함수의 범위(가시성)와 수명을 정의합니다. 그들은 컴파일러에게 변수를 어떻게 저장해야 하고, 다른 파일에서 접근할 수 있는지, 그리고 메모리에 얼마나 오래 존재해야 하는지를 알립니다.
이제 각 저장 클래스를 자세히 탐구해보겠습니다.
auto 저장 클래스
C++의 auto
키워드는 시간이 지남에 따라 의미가 달라졌습니다. 최신 C++(C++11 이후)에서는 타입 추론에 사용됩니다. 그러나 구 버전에서는 저장 클래스 지시자로 사용되었습니다.
구 사용법 (C++11 이전):
int main() {
auto int x = 5; // int x = 5;와 동일
return 0;
}
이 구 사용법에서 auto
는 자동 저장 기간을 가진 변수를 명시적으로 선언합니다. 그러나 이는 로컬 변수의 기본값이었기 때문에 거의 사용되지 않았습니다.
최신 사용법 (C++11 이후):
int main() {
auto x = 5; // x는 int로 추론됨
auto y = 3.14; // y는 double로 추론됨
auto z = "Hello"; // z는 const char*로 추론됨
return 0;
}
최신 C++에서 auto
는 초기화자에 기반하여 변수의 타입을 컴파일러가 추론하게 합니다. 복잡한 타입이나 타입이 미래에 변할 수 있는 경우에 특히 유용합니다.
register 저장 클래스
register
키워드는 이 변수가 자주 사용될 것이며 더 빠른 접근을 위해 CPU 레지스터에 유지되어야 한다는 힌트를 컴파일러에게 줍니다.
#include <iostream>
int main() {
register int counter = 0;
for(int i = 0; i < 1000000; i++) {
counter++;
}
std::cout << "Counter: " << counter << std::endl;
return 0;
}
이 예제에서 우리는 counter
를 레지스터에 유지해야 한다고 컴파일러에게 제안하고 있습니다. 그러나 현대 컴파일러는 이러한 최적화를 자동으로 수행하기 때문에 register
는 거의 사용되지 않습니다.
static 저장 클래스
static
키워드는 사용된 곳에 따라 다른 의미를 가집니다:
1. 정적 로컬 변수
#include <iostream>
void countCalls() {
static int calls = 0;
calls++;
std::cout << "This function has been called " << calls << " times." << std::endl;
}
int main() {
for(int i = 0; i < 5; i++) {
countCalls();
}
return 0;
}
이 예제에서 calls
는 초기화된 후 값을 유지하며, 함수 호출 사이에 그 값을 유지합니다. 출력은 다음과 같습니다:
This function has been called 1 times.
This function has been called 2 times.
This function has been called 3 times.
This function has been called 4 times.
This function has been called 5 times.
2. 정적 클래스 멤버
class MyClass {
public:
static int objectCount;
MyClass() {
objectCount++;
}
};
int MyClass::objectCount = 0;
int main() {
MyClass obj1;
MyClass obj2;
MyClass obj3;
std::cout << "Number of objects created: " << MyClass::objectCount << std::endl;
return 0;
}
여기서 objectCount
는 MyClass
의 모든 인스턴스에서 공유됩니다. 출력은 다음과 같습니다:
Number of objects created: 3
extern 저장 클래스
extern
키워드는 다른 파일에 정의된 글로벌 변수나 함수를 선언합니다.
파일: globals.cpp
int globalVar = 10;
파일: main.cpp
#include <iostream>
extern int globalVar; // globalVar의 선언
int main() {
std::cout << "Global variable value: " << globalVar << std::endl;
return 0;
}
이 예제에서 globalVar
는 globals.cpp
에 정의되고 main.cpp
에서 extern
으로 선언되어 있습니다. 이렇게 하면 main.cpp
가 다른 파일에서 정의된 변수를 사용할 수 있습니다.
mutable 저장 클래스
mutable
키워드는 const 객체의 멤버를 수정할 수 있도록 합니다.
class Person {
public:
Person(int age) : age(age), cacheValid(false) {}
int getAge() const {
if (!cacheValid) {
cachedAge = heavyComputation();
cacheValid = true;
}
return cachedAge;
}
private:
int age;
mutable int cachedAge;
mutable bool cacheValid;
int heavyComputation() const {
// 중한 계산을 시뮬레이션
return age;
}
};
int main() {
const Person p(30);
std::cout << p.getAge() << std::endl; // 이는 허용됩니다
return 0;
}
이 예제에서 p
는 const이지만, cachedAge
와 cacheValid
는 mutable
로 지정되어 있기 때문에 수정할 수 있습니다.
요약
우리가 배운 저장 클래스를 요약한 표를 아래에 제공합니다:
저장 클래스 | 목적 |
---|---|
auto | 타입 추론 (최신 C++) |
register | 더 빠른 접근을 위한 힌트 (Rarely used) |
static | 함수 호출 사이에서 값을 유지하거나 클래스 인스턴스 간 공유 |
extern | 다른 파일에서 정의된 변수나 함수를 선언 |
mutable | const 객체의 멤버를 수정할 수 있게 하기 |
저장 클래스를 이해하는 것은 메모리를 효율적으로 관리하고 변수의 범위를 제어하는 데 필수적입니다. C++의 여정을 계속하면서 이 개념들이 자연스럽게 습득될 것입니다. 행복한 코딩을 기원합니다!
Credits: Image by storyset