2010-04-21 6 views
4

나는 상수 정적 변수 a를 가진 기본 클래스 A를 가졌다. 클래스 B의 인스턴스가 정적 변수 a와 다른 값을 가져야합니다. 가급적 정적 인 초기화로 어떻게 이것을 달성 할 수 있습니까?C++ : 파생 클래스에서 다른 값을 가진 기본 클래스 상수 정적 변수를 초기화 하시겠습니까?

class A { 
public: 
    static const int a; 
}; 
const int A::a = 1; 

class B : public A { 
    // ??? 
    // How to set *a* to a value specific to instances of class B ? 
}; 

답변

7

수 없습니다. 파생 된 모든 클래스에서 공유하는 정적 변수의 인스턴스가 하나 있습니다.

+1

그래, 질문을 게시 한 후 발견되었습니다. 질문을 게시하고 질문을 삭제하려고 시도한 후 5시에 답변을했습니다. 귀하의 응답과 2 득표로 인해 질문을 삭제하는 것이 거부되었습니다. – chmike

3

정적 멤버는 응용 프로그램에서 고유합니다. 시스템에 하나의 A::a 상수가 있습니다.

class A { 
public: 
    static const int a = 10; 
}; 
static const int A::a; 
class B : public A { 
public: 
    static const int a = 20; 
    static void test(); 
}; 
static const int B::a; 
void B::test() { 
    std::cout << a << std::endl; // 20: B::a hides A::a 
    std::cout << A::a << std::endl; // 10: fully qualified 
} 
+0

예, 알고있었습니다. 문제는 내가 A * p = new B와 같은 포인터를 가지고있을 때입니다. p-> test()는 10과 10을 출력합니다. 그게 문제입니다. 유일한 방법은 가상 메서드를 사용하는 것 같습니다. – chmike

+0

@chmike : 다형성 (포인터/참조가 아닌 인스턴스의 실제 유형을 기반으로 한 다른 동작)이 필요한 경우 가상 메서드가 필요합니다. 예제에서 나는'A * p = new B; 'test()'가'A' 레벨에 존재하지 않기 때문에 p-> test()'는 컴파일되지 않습니다. –

+0

예, 분명히. 나는 그것을 놓쳤다. 따라서 대답은 정적 변수 a를 가상 메서드로 대체하고 파생 클래스에서 메서드를 재정의하는 것입니다. 이 메소드는 필요할 경우 정적 로컬 변수를 포함 할 수 있습니다. 간단한 코드 예제를 제공하면 해답을 알려 드리겠습니다. – chmike

3

당신은 당신이 잃을해야합니다 (Curiously recurring template pattern하여이 작업을 수행 할 수 있습니다 : 당신이 할 수있는 것은 당신이 완전한 이름을 사용하지 않는 경우합니다 (A::a 정적을 숨길 수 B에서 B::a 정적 상수를 만드는 것입니다 비록 const).

template <typename T> 
class A { 
public: 
    static int a; 
}; 

template <typename T> 
int A<T>::a = 0; 

class B : public A<B> { 
    struct helper { // change the value for A<B>::a 
     helper() { A<B>::a = 42; } 
    }; 
    static helper h; 
}; 
B::helper B::h; 
+0

이렇게하면 다른 정적 변수가 만들어집니다. –

+0

@Neil, 그렇습니다. 한 변수는 두 개의 다른 값을 가질 수 없습니다. – Motti

+0

David Rodriguez의 제안은 더 간단합니다. 여기에 템플릿을 사용하면 어떤 이점이 있습니까? – chmike

0

우리는 다음과 같이이 방법 :: 시도 할 수 있음은 아래의 장점은 코드를 여러 번 쓸 필요는 없지만, 실제 생성 된 코드가 될 수 있다는 것입니다 큰.

#include <iostream> 

using namespace std; 
template <int t> 
class Fighters { 
protected : 
    static const double Fattack; 
    double Fhealth; 
    static const double Fdamage; 
    static int count; 
public : 
    Fighters(double Fh) : Fhealth(Fh) { } 
    void FighterAttacked(double damage) { 
     Fhealth -= damage; 
    } 
    double getHealth() 
    { 
     return Fhealth; 
    } 

    static int getCount() 
    { 
     //cout << count << endl; 
     return count; 
    } 
}; 

const double Fighters<1>::Fdamage = 200.0f; 
const double Fighters<1>::Fattack = 0.6f; 
int Fighters<1>::count = 0; 

class Humans : public Fighters<1> { 
public : 
    Humans(double Fh = 250) : Fighters<1>(Fh) { count++; } 
}; 

const double Fighters<2>::Fdamage = 40.0f; 
const double Fighters<2>::Fattack = 0.4f; 
int Fighters<2>::count = 0; 

class Skeletons : public Fighters<2> { 
public : 
    Skeletons(double Fh = 50) : Fighters<2>(Fh) { count++; } 
}; 

int main() 
{ 

    Humans h[100]; 
    Skeletons s[300]; 

    cout << Humans::getCount() << endl; 
    cout << Skeletons::getCount() << endl; 

    return 0; 
} 

이것은 다른 코드 예제의 일부입니다. 다른 많은 데이터는 신경 쓸 수 있지만 개념을 볼 수 있습니다.

관련 문제