9

私の理解では、変数の をmutableキャンセルしますconstness

Class A {
  void foo() const {
  m_a = 5;
}
mutable int m_a;
};

しかしまたconst_cast:

void print (char * str)
{
  cout << str << endl;
}

int main () {
  const char * c = "this is a line";
  print ( const_cast<char *> (c) );
  return 0;
}

では、何が違うのでしょうか?

ありがとう

4

4 に答える 4

20

const_castオブジェクトの constness をキャンセルすることはできません。オブジェクトへのアクセス パスconst_castから constness のみを削除できます。アクセス パスは、オブジェクトへのポインタまたは参照です。アクセス パスから constness を削除しても、オブジェクト自体にはまったく影響しません。アクセス パスの constness を削除するために使用しても、オブジェクトを変更する権限が付与されるとは限りません。それができるかどうかは、オブジェクト自体に依存します。const の場合、それを変更することは許可されておらず、変更しようとすると未定義の動作が発生します。const_cast

たとえば、これはconst_cast

  int i = 5; // non-constant object
  const int *p = &i; // `p` is a const access path to `i`

  // Since we know that `i` is not a const, we can remove constness...
  int *q = const_cast<int *>(p);
  // ... and legally modify `i`
  *q = 10;
  // Now `i` is 10

上記が正当で有効である唯一の理由は、実際iには非定数オブジェクトであり、私たちはそれについて知っているという事実です。

元のオブジェクトが実際に定数である場合、上記のコードは未定義の動作を生成します。

  const int j = 5; // constant object
  const int *p = &j; // `p` is a const access path to `j`

  int *q = const_cast<int *>(p); // `q` is a non-const access path to `j`
  *q = 10; // UNDEFINED BEHAVIOR !!!

C++ 言語では、定数オブジェクトを変更することはできconst_castず、使用方法に関係なく、ここでは完全に無力です。

mutableは全く別物です。mutable含まれているオブジェクトが宣言されている場合でも、合法的に変更できるデータ ファイルを作成しますconst。その意味でmutable、定数オブジェクト[の指定された部分]を変更することができます。const_cast、一方、そのようなことはできません。

于 2012-07-12T18:17:14.680 に答える
4

違いは、const_castごまかすことはできませんがmutable、ルールの例外です。

最初のスニペットm_aはであり、メンバー関数mutableのデータ メンバーを変更できないという規則の例外です。const

2 番目のスニペットでconst_castは、カンニングを試みますが、実際にはできません。タイプが変更されている間、実際の変更は許可されていません。文字列は真constです。これを変更しようとすると、プログラムが未定義の動作を示す可能性があります。

于 2012-07-12T18:16:26.843 に答える
3

違いはセマンティックです。つまり、生成されたコードは同じで、実行時の結果も同じです ( constness は純粋にコンパイル時の構造です) が、2 つの構造はわずかに異なる意味を伝えます。

アイデアはmutable、クラス内にあるがオブジェクトの状態を構成しない変数に使用することです。古典的な例は、blob オブジェクト内の現在の位置です。BLOB 内を移動することは、重要な方法で BLOB を "変更" することにはなりません。を使用することmutableで、「この変数は変更される可能性がありますが、オブジェクトは同じです」と言っています。この特定のクラスでは、const-ness は「すべての変数が凍結されている」という意味ではないと述べています。

const_cast、反対に、既存の const の正確さに違反していて、それを回避したいと考えていることを意味します。おそらく、尊重しないサードパーティの API const(たとえば、古い学校の C ベースのもの) を使用しているためです。

于 2012-07-12T18:15:58.293 に答える
0

簡単に言えば、メンバー変数を宣言するmutableと、他の特別な構文を使用せずに、そのクラスの定数メソッドから書き込みアクセス可能になります。const_cast一方、定数変数への書き込みアクセスが必要な場合は常に実行する必要があり、その変数はクラスメンバーである必要はありません。

メンバー変数への書き込みアクセスを明示的に許可するconst_cast場合を除き、意図を明確に示す場合に限り、constの正当性に違反する場合は常に使用することをお勧めします。

ちなみに、const_castを使用してvolatile修飾子を追加または削除することもできます。

于 2012-07-12T18:28:26.150 に答える