2013-04-22 44 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