27

我有一个看起来像这样的遗留函数:

int Random() const
{
  return var_ ? 4 : 0;
}

我需要在该遗留代码中调用一个函数,使其现在看起来像这样:

int Random() const
{
  return var_ ? newCall(4) : 0;
}

问题是我收到了这个错误:

In member function 'virtual int Random() const':
class.cc:145: error: passing 'const int' as 'this' argument of 'int newCall(int)' discards qualifiers

现在我知道为了修复这个错误,我可以创建newCall()一个 const 函数。但是后来我必须进行几个newCall()函数调用,所以现在我必须将所有这些函数调用都设为 const。依此类推,直到最终我觉得我的程序的一半将是 const。

我的问题:有没有办法在 Random() 中调用不是 const 的函数?或者是否有人对如何newCall()Random()不使我的程序一半变为常量的情况下实现内部有任何想法。

谢谢

-乔希

4

7 回答 7

23
int Random() const
{
  return var_ ? const_cast<ClassType*>(this)->newCall(4) : 0;
}

但这不是一个好主意。如果可能,请避免!

于 2011-02-15T19:31:01.620 回答
19

应该改变你的程序以正确使用/声明 const ......

一种替代方法是使用 const_cast。

于 2011-02-15T19:31:06.567 回答
4
const_cast<MyClass *>(this)->newCall(4)

仅当您确定 newCall 不会修改“this”时才这样做。

于 2011-02-15T19:30:53.263 回答
1

这里有两种可能。首先,newCall它的所有被调用者实际上都是非修改函数。在这种情况下,您绝对应该仔细检查并标记它们const。你和未来的代码维护者都会感谢你让代码更容易阅读(这里是个人经验)。其次,newCall实际上确实会改变对象的状态(可能通过它调用的函数之一)。在这种情况下,您需要打破 API 并使Random非 const 正确地向调用者指示它修改了对象状态(如果修改只影响物理常量而不影响逻辑常量,您可以使用可变属性并传播const)。

于 2011-02-15T19:37:54.950 回答
0

如果不使用 const 强制转换,您可以尝试在方法中创建该类的新实例Random()吗?

于 2011-02-15T19:31:49.923 回答
0

const限定符断言类的实例在this操作后将保持不变,这是编译器无法自动推断的。

const_cast可以使用,但它的邪恶

于 2011-02-15T19:32:24.777 回答
0

if it's really a random number generator, then the number generation code/state could likely be placed in a class-local static generator. this way, your object is not mutated and the method may remain const.

于 2011-02-15T19:38:48.730 回答