2012-07-12 2 views
8

は、mutableは変数const_cast VSは変更可能ですか?違いは?私の理解から

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

しかし、またconst_castconstnessをキャンセル:

だから、
void print (char * str) 
{ 
    cout << str << endl; 
} 

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

、一方から他方に変更何?

ありがとうございました

答えて

16

const_castオブジェクトの定数を取り消すことはできません。 const_castは、アクセスパスからオブジェクトへのconstnessのみを削除できます。アクセスパスは、オブジェクトへのポインタまたは参照です。アクセスパスからconstnessを削除することは、オブジェクト自体に全く影響を与えません。 const_castを使用してアクセスパスの定数を削除しても、それでも必ずオブジェクトを変更する権限が与えられるとは限りません。あなたがそれを行うことができるかどうかは依然としてオブジェクト自体に依存します。それがconstの場合、あなたはそれを変更することができません。そうしたい場合、未定義の動作になります。

たとえば、これは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は、そのようなことはできません。

1

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

考えられるのは、クラス内の変数にmutableを使用しますが、オブジェクトの状態を構成しないという考えです。古典的な例は、BLOBオブジェクトの現在の位置です。ブロブ内を移動することは、ブロブを重要な意味で「変更する」とはカウントしません。 mutableを使用すると、「この変数は変更される可能性がありますが、オブジェクトは同じです」と表示されます。あなたは、この特定のクラスのために、const -nessは「すべての変数がフリーズしている」という意味ではありません。

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

4

違いはconst_castが不正行為をすることはできませんが、mutableはルールの例外です。

最初のスニペットm_amutableです。したがって、constメンバ関数のデータメンバーを変更することはできません。第二のスニペットで

は、 const_castはカンニングしようとしますが、実際にはできません。 タイプが変更されている一方で、 実際の変更は許可されていません:stringは本当に constです。それを変更しようとすると、プログラムは未定義の動作を起こします。

0

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

メンバ変数への書き込みアクセスを明示的に許可しない場合は、意思表示を明確にするためにのみ、const正確性に違反するたびにconst_castを使用することをお勧めします。

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

関連する問題