web-dev-qa-db-ja.com

const関数内で非const関数を呼び出す方法(C ++)

私は次のようなレガシー関数を持っています:

_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になるように感じます。

私の質問:constではないRandom()内の関数を呼び出す方法はありますか?または、私のプログラムの半分をconstにすることなく、newCall()内にRandom()を実装する方法について誰かがアイデアを持っていますか。

ありがとう

-ジョシュ

22
Grammin

you should constを正しく使用/宣言するようにプログラムを変更します...

1つの代替方法は、const_castを使用することです。

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

しかし、それは良い考えではありません。可能であれば避けてください!

17
Nawaz
const_cast<MyClass *>(this)->newCall(4)

NewCallが「this」を変更しないことが確実な場合にのみこれを行ってください。

3
Erik

ここには2つの可能性があります。まず、newCallとその呼び出し先のすべてが、実際には変更しない関数です。その場合、あなたは絶対に通り抜け、それらすべてにconstをマークする必要があります。あなたと将来のコードメンテナの両方が、コードをはるかに読みやすくしてくれたことに感謝します(ここでの個人的な経験から言えば)。次に、newCallは実際にオブジェクトの状態を変更します(おそらくそれが呼び出す関数の1つを介して)。この場合、APIを中断し、Randomを非constにして、オブジェクトの状態を変更することを呼び出し元に適切に示す必要があります(変更が物理的な恒常性にのみ影響し、論理的な恒常性には影響しない場合は、可変属性を使用して伝播できますconst)。

1
Mark B

それが実際に乱数ジェネレーターである場合、数値生成コード/状態は、クラスローカル静的ジェネレーターに配置される可能性があります。このように、オブジェクトは変更されず、メソッドはconstのままになる可能性があります。

0
justin

Constキャストを使用せずに、Random()メソッドでクラスの新しいインスタンスを作成してみてください。

0
Coffee on Mars

const修飾子は、クラスのインスタンスthisが操作後に変更されないことを表明します。これは、コンパイラーが自動的に推測できないものです。

const_cast使用できますが、その悪

0
Foo Bah