문제의 역사
정적 클래스 멤버는 모든 객체에 공통적인 값이나 특정 클래스 인스턴스에 바인딩되지 않은 함수를 저장할 수 있도록 C++에서 등장했습니다. 예를 들어, 카운터, 객체 팩토리 또는 도우미 함수를 저장하는 데 유용합니다.
문제
항상 문제는 이러한 멤버의 유효 범위와 초기화 시점이었습니다. 프로그램에 많은 소스 파일이 있는 경우 특히 그렇습니다. static 멤버를 잘못 정의하면 링크 오류가 발생합니다.
해결책
C++에서 static 멤버는 클래스 정의 내에서 선언되지만, 변수의 초기화는 별도로 cpp 파일에서 이루어져야 합니다( C++17 이전). C++17에서는 constexpr인 경우 선언 내에서 직접 초기화할 수 있습니다.
코드 예:
class MyClass { public: static int counter; static void increment() { ++counter; } }; int MyClass::counter = 0; // 클래스 외부에서 초기화는 필수입니다.
주요 특징:
cpp 파일에서 static 멤버를 정의하지 않으면 어떻게 됩니까?
링크 오류가 발생합니다. 정적 변수는 선언되지만 정의되지 않았기 때문입니다. 예외는 static const int가 constexpr 값에 대해 클래스 내부에서 직접 초기화된 경우입니다.
// .h class A { public: static int x; }; // .cpp // int A::x = 0; // 주석 처리되면 오류 발생
정적 함수에서 비정적 함수를 호출할 수 있습니까?
아니요. 정적 함수는 this 포인터와 비정적 멤버에 직접 접근할 수 없습니다. 접근하려면 특정 객체가 필요합니다.
class B { int data; static void foo() { // data = 3; // 오류 } };
정적 변수는 모든 인스턴스에 대해 동일합니까?
네, 같은 실행 파일 및 프로세스 내에서 모든 인스턴스에 대해 같은 값입니다.
팀이 cpp 파일에서 static 멤버를 정의하는 것을 잊어버려서 프로젝트가 주기적으로 오류와 함께 빌드되고, 때때로 인라인 초기화 사용 시(모든 컴파일러에서가 아니며) "신비로운" 실행 오류가 발생합니다.
장점:
단점:
회사는 모든 클래스에 대해 static 멤버가 항상 cpp 파일에서 정의되도록 규칙을 정했습니다. 스레드 안전성을 위해 std::mutex 또는 원자 연산을 사용합니다.
장점:
단점: