2012-03-20 2 views
2

알다시피, 클래스 구조 내에서 정수 const 정적 멤버를 초기화 할 수 있습니다. 이것은 클래스 구조에서 상수가 클래스 구조에서 사용될 때 유용합니다. 예를 들어 int 배열의 크기로 사용할 수 있습니다.클래스 내에서 초기화되는 const 정적 멤버를 정의해야하는 이유

class MyClass{ 
static const int num = 100; 
int elems[num]; 
... 
}; 

을하지만 우리는 여전히 클래스 정의 외부에 멤버 NUM을 정의 할 수 있습니다 : 다음 코드를 봐

const int MyClass::num; 

우리가 같이해야 할 이유를 모르겠어요. 누군가 내게 이유를 말해 줄 수 있습니까? 고마워요. 비주얼 스튜디오 2008에서 잘

#include <iostream> 
using namespace std; 

class MyClass{ 
public: 
MyClass() 
{ 
    cout << "instruct class MyClass!" << endl; 
} 
static const int num = 100; 
int elems[num]; 
}; 

//const int MyClass::num; 

int main() 
{ 
MyClass a; 
const int *b = &(a.num); 
cout << "&(a.num): " << &(a.num) << endl; 
cout << "a.num: " << a.num << endl; 
cout << "*b: " << *b << endl; 
} 

그것은 실행 :

은 또한, 나는 다음과 같은 코드를 작성

enter image description here

하지만 코드를 제거했는지 명확한 회원 NUM 수업 외부.

나는 매우 혼란 스럽다. 누군가 나를 위해 그것을 해석 할 수 있습니까?

답변

5

클래스의 초기화는 주로 상수 표현식을 얻는 데 사용됩니다. 이것을 위해서만 가치가 중요합니다. 개체의 주소를 가져 오거나 참조로 바인딩하면 컴파일러는 개체의 위치도 필요로합니다. 이것은 실제로 정의가 제공하는 것입니다.

+1

그러나 컴파일러는 템플릿의 정적 멤버 또는 인라인 함수를 처리하는 것과 동일한 방식으로 처리 할 수 ​​있습니다. 둘 다 정의는 여러 파일이지만 하나의 주소가 필요합니다. –

+0

@JamesKanze : 템플릿의 정적 멤버의 경우 암시 적 인스턴스 생성이이 작업을 수행하지 않으므로 실제로는 성가신 정의가 필요합니다. 인라인 함수에서 정적 변수처럼 동작하도록 만들 수 있습니다. 필자가 알고있는 점은 링크 시간에 버려지는 약한 기호로 함수를 작성함으로써 이러한 작업이 가능하다는 것입니다. 그러나 컴파일러는 현재 언어가 존재한다고 주장하지는 않지만 정의를 요구합니다. –

+0

알아. 기술적으로, 정의를 요구하지 않는 것은 문제가되지 않을 것이라고 말하는 것입니다. 컴파일러 기술을 필요로하지 않는 것을 지원하는 것이 다른 상황에서도 필요하기 때문입니다. –

4

당신은 당신의 코드가 걸리는 경우에만이 address.This가 로 알려져있어 CPP 파일에서 클래스 외부 정적 상수 num를 정의 할 필요가 밖으로의 클래스 정의.
코드의 주소가 num 인 경우 클래스 초기화 인은 정상적으로 작동합니다.

이론적 근거 :

비얀 states :

"C++은 모든 개체가 고유 정의가 그 규칙이 파괴 될 수 있어야 할 필요가 개체의 수준의 정의를 허용 C++ 경우. 개체로 메모리에 저장됩니다. "

static const 정수 만 컴파일 타임 상수로 취급 할 수 있습니다. 컴파일러는 정수 값이 언제든지 변경되지 않으므로 자체 마법을 적용하고 최적화를 적용 할 수 있음을 알고 컴파일러는 이러한 클래스 멤버를 간단히 인라인합니다. 즉 메모리에 더 이상 저장되지 않습니다. 메모리에 저장해야하는 필요성이 제거됨에 따라 , 그런 변수는 Bjarne에 의해 언급 된 위의 규칙에 예외를 준다.

static const 정수 값이 인트 클래스 초기화를 가질 수있는 경우에도 이러한 변수의 주소는 허용되지 않습니다. 컴파일러가 클래스를 메모리에 저장해야하기 때문에 클래스에 정의가없는 경우에만 정적 멤버의 주소를 사용할 수 있습니다.

+0

마지막으로 이해합니다. 답장을 보내 주셔서 감사합니다. – XiaJun

관련 문제