2013-04-22 2 views
0

A * 길 찾기 알고리즘이있는 라이브러리 (libtcod)를 사용하고 있습니다. 내 클래스는 콜백 기본 클래스를 상속하고 필요한 콜백 함수를 구현합니다. 여기 내 일반적인 예는 다음과 같습니다const 함수 재 작성

class MyClass : public ITCODPathCallback 
{ 
... 
public: // The callback function 
    float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData) const 
    { 
     return this->doSomeMath(); 
    }; 
    float doSomeMath() { // non-const stuff } 
}; 

나는에 const_cast 및 static_cast를 사용하여 예제의 번호를 찾았지만 그들은 const가 아닌 함수는 const를 함수 결과를 반환 할 수있어 다른 방법으로 갈 것 같았다. 이 예제에서는 어떻게 할 수 있습니까?

getWalkCost()는 변경할 수없는 내 라이브러리에 의해 정의되어 있지만, const가 아닌 것을 할 수 있기를 원합니다.

+1

정말 확실합니까? 당신은 getWalkCost 계약을 위반하고 있다는 것을 알고 있습니다. 아무 것도 수정하지 않는다고 약속합니다. –

답변

6

최상의 솔루션은 비 const 자료를 원하는 이유에 따라 다릅니다.

class MyClass : public ITCODPathCallback 
{ 
... 
public: // The callback function 
    float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData) const 
    { 
     return this->doSomeMath(); 
    }; 
    float doSomeMath() const { // ok to modify cache here } 
    mutable std::map<int,int> cache; 
}; 

아니면 당신이 어떤 통계를 기록 할 : 당신은 당신이 성능을 향상하는 데 사용할 결과의 캐시가있는 경우 그 논리 const와 보존하기 때문에 예를 들어, 당신은 캐시가 가변 될 수 있습니다 getWalkCost가 호출 된 횟수와 최대 x 값이 무엇인지에 대해 통계에 대한 참조를 전달하는 것이 가장 좋을 수 있습니다.

class MyClass : public ITCODPathCallback 
{ 
... 
public: 
    struct WalkStatistics { 
    int number_of_calls; 
    int max_x_value; 

    WalkStatistics() : number_of_calls(0), max_x_value(0) { } 
    }; 

    MyClass(WalkStatistics &walk_statistics) 
    : walk_statistics(walk_statistics) 
    { 
    } 

    // The callback function 
    float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData) const 
    { 
     return this->doSomeMath(); 
    }; 
    float doSomeMath() const { // ok to modify walk_statistics members here } 
    WalkStatistics &walk_statistics; 
}; 
+0

또한'const' 함수를 통해 객체를 수정할 때 쓰레드 안전성에 대해서 생각해 봐야합니다. 객체가 단일 스레드에서만 사용되기 때문에 그것에 대해 아무 것도 할 필요가 없다는 것을 깨닫기에 충분하다고 생각하더라도. –

1

당신은 이런 식으로 해킹 할 수

이 대부분의 사람들이 좋은 디자인 고려되지 않습니다 물론
return const_cast<MyClass*>(this)->doSomeMath(); 

하지만, 헤이. 원하는 경우 doSomeMath() const를 대신 작성하고 수정하는 데이터 멤버를 mutable으로 표시 할 수 있습니다.