2009-08-25 5 views
7

두 개의 파일을 연결하지 못했습니다. "정적"키워드를 제거하면 괜찮습니다. g ++로 테스트되었습니다. readelf를 사용하여 개체 파일을 확인하십시오. 정적 멤버는 전역 개체 심볼로 내보내집니다 ... 로컬 개체라고 생각합니다 ...?정적 멤버에 대한 다중 정의?

static1.cpp

class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
void first() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 

오류 정보와 static2.cpp

class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
void second() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 

:

/tmp/ccIdHsDm.o:(.bss+0x0) : 여러 `StaticClass :: a '의 정의

답변

16

각 소스 파일에 같은 이름의 로컬 클래스가있는 것처럼 보입니다. C++에서 당신은 익명의 네임 스페이스에 현지 클래스를 캡슐화 할 수 있습니다

namespace { 
class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
} // close namespace 

void first() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 
+0

@Ropez : 잘 작동합니다. 고마워요 :) –

+0

로페즈의 대답이 당신에게 당신이 찾고있는 해결책을 제시 한 것 같아서, 나는 사태에 대해 나쁘다고 느낍니다. 체크 마크를 자유롭게 움직여서 +1 할 수 있습니다. 어쨌든 +1하십시오. –

+0

@Litb, 둘 다 맞습니다 :) 더 설명했습니다. –

0

StaticClass은 모든 클래스 인스턴스가 공유 할 정적 변수 인 a을 저장할 장소가 필요합니다. 각 행에 두 개의 행이 있으므로 각 파일에 하나씩 있습니다. 하나를 제거하면 링커 오류가 해결됩니다.

9

다음은 정적 데이터 멤버의 정의입니다. 그것은 컴파일되고 링크 된 하나의 파일에서만 발생해야합니다. 여러 이러한 정의가 경우 first라는 여러 기능을 가진 것처럼

int StaticClass::a = 0; 

, 그것은이다. 그들은 충돌 할 것이고 링커는 불평 할 것이다.

정적 멤버를 네임 스페이스 범위 변수에 정적으로 적용하는 것을 잘못 생각한다고 생각합니다. 네임 스페이스 수준에서 static은 변수 또는 참조 내부 연결을 제공합니다. 그러나 클래스 범위 수준 (멤버에 적용 할 때)은 정적 멤버가됩니다. 정적 멤버는 각 객체 대신 클래스에 개별적으로 바인딩됩니다. 그런 다음 "정적"이라는 C의 의미와 더 이상 관련이 없습니다. 이 한 번만 작성해야하는 이유

+0

문제는 내가 링커는 로컬 오브젝트 파일에 변수를 연결 알아야 할 생각입니다,이 지역 정적 변수가 아닌 글로벌 정적이기 때문에 하나. –

+0

로컬이 아니며 글로벌도 아닙니다. 그것은 반원입니다. http://en.wikipedia.org/wiki/Class_variable –

+2

@arsane 로캘 클래스를 원한다면 익명의 네임 스페이스에 넣어야합니다.이것을 쓰면 static1.cpp의 StaticClass는 static2.cpp의 StaticClass와 같은 클래스입니다. 클래스가 헤더에 정의되어 있지 않다고 말하기 전에 매크로 처리기가 텍스트 포함으로 작동한다는 것을 잊지 마십시오. – AProgrammer

2

int StaticClass::a = 0; 

실제로 변수에 대한 스토리지를 할당 문이있다.

귀하의 의견에 따르면, 아마도 static 키워드의 두 가지 용도가 혼동을 일으킬 수 있습니다. "내부 연결 사용"을 의미하는 C 정적에서 변수 또는 함수의 이름은 정의 된 변환 단위 외부에서 볼 수 없다는 것을 의미합니다.

클래스에서 static은 클래스 멤버를 정의하는 데 사용됩니다. 클래스 멤버는 클래스의 특정 인스턴스를 참조하지 않는 변수 또는 메서드입니다. 이 경우 정적 변수에 대한 저장소는 어딘가에 (즉, 인스턴스의 일부가 아니므로) 할당되어야하지만 물론 한 곳에서만 할당되어야합니다.

관련 문제