2012-01-25 2 views
3

"부모"클래스를 만들려고합니다. 공용 생성자와 매개 변수 유형을 모두 상속 된 클래스에 제공합니다. 상속 된 것 사이에서 변경되는 유일한 것은 정적 변수의 값입니다.상속 된 클래스에서 정적 변수를 초기화하는 방법은 무엇입니까?

이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

class Ball { 
    public: 
    virtual ~Ball(); 
    Ball(); 

    protected: 
    static string file; 
    static int size; 
    node shape; 
}; 

class TenisBall: public Ball {}; 
class OtherBall: public Ball {}; 

Ball::Ball() { 
    shape = // do something with file and size 
}; 

Ball::~Ball() { 
    delete shape; 
}; 

string TenisBall::file = "SomeFile"; 
int TenisBall::size = 20; 

string OtherBall::file = "OtherFile"; 
int OtherBall::size = 16; 

내 문제는 다음과 같습니다 : 이것은 내 현재 시도 내가 코드의 마지막 두 줄 Ball에 대한 TenisBallOtherBall을 변경하면 나는 TenisBallOtherBall 클래스의 정적 값을 설정할 수 없습니다, 컴파일러는 받아들입니다. 어떻게해야합니까? 이것이 최선의 접근 방법입니까?

편집 :

는 제공된 답변에 따라, 나는 가상 함수를 사용하여 구현을 시도하기로 결정했다.

class Ball { 
    public: 
    Ball() { 
     shape = // do something with getSize and getFile 
    }; 

    ~Ball() { 
     delete shape; 
    }; 

    protected: 
    virtual string getFile(){ return "Fake"; }; 
    virtual int getSize(){ return 10; }; 

    node shape; 
}; 

class TenisBall: public Ball { 
    int getSize() { return 16; }; 
    string getFile() { return "TennisBall.jpg"; }; 
}; 

int main() { 
    TenisBall ball; 
    return 1; 
}; 

하지만 내 편집기 (엑스 코드)이 오류를 제공하지 않는 동안 컴파일하려고 할 때, LLVM은 다음과 같은 오류 제공 : 여기 내 코드는 지금까지입니다

invalid character '_' in Bundle Identifier at column 22. This string must be a uniform type identifier (UTI) that contains only alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.) characters.

+2

IMO 여기에 올바른 디자인에서 정적 멤버를 사용하지 않는 것입니다 모두 (같은 크기의 모든 공은 모두 똑같은 것으로 보입니까?) 의심 스럽습니다. – stijn

+1

관련 항목 : http://stackoverflow.com/questions/998247/are-static-members-inherited-c - static members don ' 네가 상속 재산처럼 행동하지 마라. – Mat

+0

기본 클래스는 정적 변수를 파생 클래스와 공유합니다. 파생 클래스에서 초기화하는 것은 의미가 없습니다. –

답변

4

당신이하려고 무엇을 불가능합니다. 클래스에서 정적 변수가 선언되면이 클래스에 하나의 변수 만 있고 심지어 파생 클래스도이를 변경할 수 없으므로 Ball::file을 변경하면 TennisBall에 대해 다른 것을 수행 할 수 없습니다.

가장 쉬운 해결 방법은 아마도 가상 함수에 Ball::file을 변경하는 것 (반환하는 경우에도 클래스 - 나 기능 - 정적 일 수있는 일에 string 또는 string&)는 파생 클래스에서 재정의 할 수 있습니다.

+0

그래, 이것이 유일한 방법 일 경우 알맞습니다. 고맙습니다! – Jaliborc

+0

나는 당신의 접근 방식을 통해 그것을 구현할 수 없다. 나는 초기 질문을 편집했다. – Jaliborc

+0

Ups : 아니요, 마지막 코멘트를 잊어 버렸습니다. 두 가지 주요 기능이있었습니다. – Jaliborc

0

확실하게 통계는 없습니다. 사용하면 파생 클래스의 인스턴스 수에 관계없이 메모리에 데이터 복사본이 하나씩 있으므로 매번 데이터를 덮어 쓰게됩니다.

크기와 파일 이름을 처리하는 Ball의 한 일반적인 생성자는 어떻습니까? 각 파생 클래스가 자신의 정적 변수를 가지고 싶다면

class Ball { 
    public: 
    virtual ~Ball(); 
    Ball(); 
    Ball (int curr_size, string curr_filename); 

    protected: 
    string file; 
    int size; 
    node shape; 
}; 

class TenisBall: public Ball { 
    TennisBall(int size, string filename) 
    :this(curr_size, curr_filename) 
    { 
    } 


}; 
class OtherBall: public Ball { 
    OtherBall(int size, string filename) 
    : this(curr_size, curr_filename) 
    { 
    } 

}; 

Ball::Ball() { 
    shape = // do something with file and size 
}; 

Ball::Ball(int curr_size, string curr_filename) { 
    shape = // whatever 
    curr_size = size; 
    curr_filename = filename; 
} 

Ball::~Ball() { 
    delete shape; 
}; 

// .... 
Ball *b = new TennisBall(16, "c:/tennisball_photo.jpg"); 

delete b; 
1

, 당신은 바스 클래스를 템플릿을 만들어 사용할 수 있습니다 CRTP :

template<typename T> 
class Ball { 
    static int size; 
}; 

template<typename T> int Ball<T>::size = 0; 

class TennisBall : public Ball<TennisBall> { 

}; 

template<> int Ball<TennisBall>::size = 42; 
+0

좋은 생각이지만 가상 기능을 사용할 때와 똑같은 오류를 계속 발생시킵니다. – Jaliborc

+0

Ups : 아니요, 잊어 버리십시오. 저는 두 가지 주요 기능을했습니다. – Jaliborc

관련 문제