4

const_cast を使用してポインターの const-ness を削除することは避けるべきであることは誰もが知っていることです。

しかし、その逆はどうでしょうか。

私の使用例では、const 以外のソース バッファーからデータ (バイト) をコピーする関数があります。そのソース バッファーに従ってパラメーターを完全に const として宣言することは、適切な設計上の決定であると考えました。

void copyfunction(const char* const data) { ... }

以下のような関数呼び出しでは、ポインタ型エラー 'const char* const <-> char*' が発生します。

void main() {
    char sourcebuffer[] = {0x00};

    copyfunction(sourcebuffer);
}

確かに、これで単純にsourcebufferas const を宣言できましたが、私の場合、別のコードの場所 (外部ライブラリ) からのものであるため、その変数にアクセスできません。

void main() {
    char sourcebuffer[] = {0x00};

    copyfunction(const_cast<const char* const>(sourcebuffer));
}

ただし、それを超えるコードは機能しますが、それは良いスタイルですか (私のユースケースによると)?

as constのパラメーターを宣言するcopyfunctionことで、ユーザーはポインターまたはソースバッファー自体の場所を変更 (読み取り専用) しないことが保証されると思いました。したがって、この場合、 const_cast は、関数呼び出しを有効にするために必要な悪にすぎず、ポインターの const-ness を意図的に削除することはありません...

あいさつ

4

2 に答える 2

6

次の理由により、 を使用const_castして add を使用しないでください。const

  1. それは不要です。T*に暗黙的に変換されconst T*ます。あなたの質問はそれchar sourcebuffer[] = {0x00}; copyfunction(sourcebuffer);がエラーであると述べていますが、それは真実ではありません。

  2. 潜在的に (可能性は低いですが) 有害です。ポインター型から削除できますが、これはここでの意図ではなく、として宣言されたvolatile場合に未定義の動作が発生する可能性があります。sourcebuffervolatile sourcebuffer[]

于 2014-01-06T18:58:58.273 に答える
5

const_castadd には使用しconstないでください。

  1. 操作が安全な場合は、ほとんどの場合必要ありません。 暗黙的int*に に変わります。const int*

  2. それはあなたがしたくないことをすることができます。を削除するか、変数の別の場所に追加されvolatileたという事実を見逃す可能性があり、今では静かにそれらを削除します。constconst_cast

  3. を追加する必要がある場合const、その使用は理由がわかりにくいので危険です。

const_cast追加するために呼び出す必要がある場合がありますが、これはconst暗黙的に行われません。

void assign_ptr( int const*& lhs, int const* rhs ) { lhs = rhs; }
int const foo = 7;
int* bar = nullptr;
assign_ptr( const_cast<int const*&>(bar), &foo );
*bar = 2; // undefined behavior!
std::cout << foo << "@" << &foo << "\n"; // will print probably 7@something
std::cout << *bar << "@" << bar << "\n"; // will print probably 2@same address as above!

上記の呼び出しは をassign_ptr追加するだけですがconst、暗黙的には発生しません。

その副作用は*bar、宣言された変数を変更するため、 の変更が未定義の動作になることですconst( bar、 a 、 aint*を指すようにしfooますconst int)。

したがって、呼び出しをコンパイルするにconst_castは が必要ですが、それは unsafe だったためです。は安全にするわけではなく、エラーを隠すだけです。assign_ptrconst_cast

これは、長方形と正方形の問題の特定のケースです。正方形の幅を変更すると高さも変更されるため、正方形は長方形ではありません。これは、長方形を変更しても発生しません。同様に、int**ありませんint const**。(不変の Squares は不変の Rectangle の一種であることに注意してください。問題を引き起こすのは突然変異です。ポインターの場合、 aint*const*は aint const*const*です。「より高いレベルの」ポインターの可変性が問題を引き起こします。)

于 2014-01-06T19:25:05.500 に答える