2013-04-22 46 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()由我的庫定義,我無法更改,但我希望能夠在其中執行非常量事情。

+1

您確定嗎?你意識到你違反了getWalkCost的合約,它承諾它不會修改任何東西。 – 2013-04-22 13:54:31

回答

6

最好的解決方案取決於你爲什麼要做非常量的東西。例如,如果您有您要使用來提高性能結果的緩存,那麼你可以讓緩存是可變的,因爲它保留了邏輯常量性:

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; 
}; 

或者,也許你想記錄一些統計數據關於調用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'函數修改對象時考慮線程安全性。即使你只是想了很長時間才意識到你不需要做任何事情,因爲對象只會被單個線程使用。 – 2013-04-22 14:08:19

1

你能砍這樣說:

return const_cast<MyClass*>(this)->doSomeMath(); 

當然,這不會被大多數人認爲好的設計,但嘿。如果你喜歡,你可以改爲doSomeMath()const,並將它修改的數據成員標記爲mutable