2013-04-29 3 views
-2
class ClassObject { 
public: 
    ClassObject(); 
    virtual ~ClassObject(); 
private: 
    int x; 
}; 

int ClassObject::x=10; 

왜 컴파일에 실패합니까? 정적 멤버를이 방법으로 초기화 할 수 있다면 비 정적 멤버에도 가능해야한다고 생각합니다.클래스 선언 외부의 비 정적 멤버를 초기화 할 수없는 이유는 무엇입니까?

+6

당신은 어떻게 생각하십니까? – 0x499602D2

+0

하지만 정적이 아닌 경우 개체에 설정해야하며 여기에 개체가 없습니다. ... 또는 새 객체를 만들 때 초기화에 대한 기본값을 의미합니까? 즉,이 코드를 생성자 밖으로 이동하면됩니까? – Rup

+0

만약'x'가 10이 아닌 다른 값을 원한다면? – yngccc

답변

5

정적 멤버는 특별합니다. 클래스가 정의되면 즉시 할당 된 메모리가입니다. 그리고 그 클래스의 얼마나 많은 객체가 모든 객체를 만들지라도 동일한 메모리를 참조합니다.

정적이 아닌 구성원의 경우에는 해당되지 않습니다. 특정 클래스의 객체를 만들지 않는 한 비 정적 멤버는 메모리가 할당되지 않으므로 위의 방법으로 인스턴스를 만들려고하면 컴파일러 오류가 발생합니다. 난 당신이 새로운 ClassObject에 대한 x을 초기화하는 데 사용되는 값을 선언하는 의미 같은데요

0

, 당신은 같은 상당

ClassObject() : x(10) { } 

당신의 구문 문제는 컴파일러가 코드를 생성 할 필요가 있다는 것을 의미 즉, 모든 ClassObject 생성자에서 초기화를 수행하십시오. 즉, 모든 생성자를 정의하는 컴파일 단위 및 암시 적으로 생성하는 컴파일 단위에서 int ClassObject::x = 10; 초기화가 사용 가능한 경우에만 작동 할 수 있습니다. 그리고 값을 클래스 정의 내부에 설정하면 외부에서 값을 설정하는 것만 큼 확실하게 보장 할 수 있습니다. (그러나 이제는 C++ 11에서 가능합니다 - tacp의 코멘트에있는 링크를 참조하십시오.)

구문을 작동 시키려면 선언 된 값을 다음 위치에 숨겨진 정적으로 저장해야합니다. 임의의 생성자가이 값을 가져와 x의 초기 값으로 사용한다는 것을 알 수 있습니다. 그러나이 정적은 존재할 수도 있고 존재하지 않을 수도 있으며, 다른 컴파일 유닛의 생성자가 링크 타임에 있다는 것을 알 수있는 유일한 포인트입니다. 따라서 우리는 여분의 여분의 코드를 생성하여이 숨겨진 정적 (존재하지 않는 데이터)이 있으면이를 초기화하거나 링크 타임 코드 생성을 요구하여 컴파일러 개발자에게 큰 부담을줍니다. 가능 합니다만, 허용되지 않으면 모든 곳에서 더 간단합니다.