3

定数として宣言されたオブジェクトを変更することが UB であることは知っています。タイトルで言及されているより複雑な例はどうですか?

class Foo
{
    public:
        Foo ( void ) { }
        int data;
};

int main ( void )
{
    const Foo foo;
    const_cast<Foo&>(foo).data = 0;   //  UB?
    return 0;
}

data非 const として宣言されているので、変更しても問題ありません。ただし、fooconstとして宣言されています。そのため、変更することはできないようです。したがって、ここで UB が呼び出されると思います。私は正しいですか?

更新:実際には UB であることがわかります。これは、可変メンバーを変更する偽の定数メンバーを持つすべてのクラスが、定数インスタンスで UB を生成することを意味します。

class Foo
{
    public:
        mutable int data;
        Foo ( void ) { }
        void foo ( void ) const
        {
            some_modifications_of_data();
        }
};


const Foo foo;
foo.foo(); // UB?

この種のクラスを設計する場合、いかなる状況下でも誰もこのメソッドを定数インスタンスで呼び出すことができないことを明示的に言及する必要があるということですか?

4

1 に答える 1

5

を使用const_castしてデータ構造内のデータを変更することは、const実際には未定義の動作です。例外は マークの付いたアイテムmutableです。これらの値の全体的なポイントは、オブジェクトの残りの部分がconst. それは本当に「しかし、これはそうではありませんconst」という意味です。

ほぼすべてがconst変更を検出するコンパイラに関するものであるため、技術的には、コンパイラはいくつかのconst変数を「書き込み不可能なメモリ」に配置することが許可されています。mutableキーワードは constness の「バイパス」を許可するためのものであるため、可変コンポーネントがある場合、コンパイラはオブジェクトを書き込み不可のメモリに配置しません。constもちろん、const変更されるオブジェクトに「オブジェクト」しません。それは変更可能なコンポーネントです-const関数内であっても。

于 2013-07-24T10:24:35.830 に答える