static
members
클래스 정의 내부에서, 키워드 static 는 클래스 인스턴스에 바인딩되지 않는 멤버들을 선언합니다.
클래스 정의 외부에서는 다른 의미를 가집니다: storage duration 을 참조하십시오.
목차구문정적 멤버에 대한 선언은 선언 지정자에 키워드 static이 포함된 멤버 선언입니다. 키워드 모든 정적 데이터 멤버와 정적 멤버 함수의 이름은 포함하는 클래스의 이름과 달라야 합니다. 설명클래스의 정적 멤버들은 클래스 객체와 연관되지 않습니다: 이들은 정적 또는 스레드 (since C++11) storage duration 을 가지는 독립 변수이거나 일반 함수입니다. static 키워드는 클래스 정의 내부에서 static 멤버의 선언에만 사용되며, 해당 static 멤버의 정의에는 사용되지 않습니다: class X { static int n; }; // 선언 ('static' 사용) int X::n = 1; // 정의 ('static' 사용하지 않음) 클래스 본문 내의 선언은 정의가 아니며, 멤버를 불완전한 타입 ( void 제외)으로 선언할 수 있으며, 여기에는 해당 멤버가 선언된 타입 자체도 포함됩니다: struct Foo; struct S { static int a[]; // 선언, 불완전 타입 static Foo x; // 선언, 불완전 타입 static S s; // 선언, 불완전 타입 (자체 정의 내부) }; int S::a[10]; // 정의, 완전 타입 struct Foo {}; Foo S::x; // 정의, 완전 타입 S S::s; // 정의, 완전 타입
클래스
struct X { static void f(); // 선언 static int n; // 선언 }; X g() { return X(); } // X를 반환하는 함수 void f() { X::f(); // X::f는 정적 멤버 함수의 한정된 이름 g().f(); // g().f는 정적 멤버 함수를 참조하는 멤버 접근 표현식 } int X::n = 7; // 정의 void X::f() // 정의 { n = 1; // X::n은 이 스코프에서 단순히 n으로 접근 가능 } 정적 멤버는 클래스 멤버 접근 규칙(private, protected, public) 을 따릅니다. 정적 멤버 함수정적 멤버 함수는 어떤 객체와도 연관되지 않습니다. 호출될 때, 이들은 this 포인터를 가지지 않습니다. 정적 멤버 함수는 virtual , const , volatile , 또는 ref-qualified 로 선언될 수 없습니다. 정적 멤버 함수의 주소는 일반적인 함수 포인터 에 저장될 수 있지만, 멤버 함수 포인터 에는 저장될 수 없습니다. 정적 데이터 멤버는 어떤 객체와도 연결되지 않습니다. 클래스의 객체가 정의되지 않아도 존재합니다. 정적 데이터 멤버는 정적 저장 기간을 가지며 프로그램 전체에 하나의 인스턴스만 존재합니다. 단, thread_local 키워드를 사용하는 경우 스레드 저장 기간을 가지며 스레드당 하나의 객체가 존재합니다(C++11부터). 정적 데이터 멤버는 네임스페이스 범위에 있는 클래스의 정적 데이터 멤버는 외부 링크를 가집니다. 단, 클래스 자체가 외부 링크를 가지는 경우(즉, 명명되지 않은 네임스페이스의 멤버가 아닌 경우)에만 해당됩니다. 지역 클래스(함수 내부에 정의된 클래스)와 명명되지 않은 클래스(명명되지 않은 클래스의 멤버 클래스 포함)는 정적 데이터 멤버를 가질 수 없습니다.
상수 정적 멤버정수형이나 열거형의 정적 데이터 멤버가 const (그리고 volatile 가 아닌)로 선언된 경우, 모든 표현식이 초기화 에서 상수 표현식 인 이니셜라이저를 사용하여 클래스 정의 내부에서 직접 초기화될 수 있습니다: struct X { const static int n = 1; const static int m{2}; // C++11부터 const static int k; }; const int X::k = 3;
const non-inline (since C++17) static 데이터 멤버 또는 constexpr static 데이터 멤버 (since C++11) (until C++17) 가 ODR-use 되는 경우, 네임스페이스 범위에서의 정의가 여전히 필요하지만 초기화자를 가질 수 없습니다.
struct X { static const int n = 1; static constexpr int m = 4; }; const int *p = &X::n, *q = &X::m; // X::n과 X::m은 ODR-사용됨 const int X::n; // … 따라서 정의가 필요함 constexpr int X::m; // … (C++17에서는 X::m 제외) 키워드결함 보고서다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
참고문헌
참고 항목 |