14

誰の助けを借りてconst_castも、宣言された定数オブジェクトを変更できるため、const修飾子は何に使用されますか?

constとにかく、彼が宣言したものが変更されないことを誰かがどのように保証できるのでしょうか?

4

4 に答える 4

12

その通りです。多くの場合、 の使用はconst_cast設計上の欠陥、または制御できない API を示しています。

ただし、例外があり、オーバーロードされた関数のコンテキストで役立ちます。本C++ Primerから例を引用しています。

// return a reference to the shorter of two strings
const string &shorterString(const string &s1, const string &s2)
{
    return s1.size() <= s2.size() ? s1 : s2;
}

この関数は、 への参照を受け取って返しますconst string。非 conststring引数のペアで関数を呼び出すことができますがconst string、結果として a への参照を取得します。shorterStringconst 以外の引数を指定すると、単純な参照が生成されるバージョンが必要になる場合があります。を使用して、このバージョンの関数を記述できますconst_cast

string &shorterString(string &s1, string &s2)
{
    auto &r = shorterString(const_cast<const string&>(s1),
                            const_cast<const string&>(s2));
    return const_cast<string&>(r);
}

shorterStringこのバージョンは、引数を への参照にキャストすることにより、 の const バージョンを呼び出しますconstconst stringその関数は、元の非 const 引数の 1 つにバインドされていることがわかっているa への参照を返します。したがって、リターンでその文字列をプレーンにキャストしても安全であることがわかっていますstring&

于 2013-09-17T05:42:39.560 に答える
7

const_castconstもともと非 const 変数に追加する場合にのみ安全です。const元々 const であったオブジェクトからステータスを削除してから書き込み操作を実行しようとすると、未定義の動作が発生します。

この質問は関連しています。

また、msdnページには次のように書かれています(強調は私のものです):

任意のオブジェクト型へのポインターまたはデータ メンバーへのポインターは、const、volatile、および __unaligned 修飾子を除いて同一の型に明示的に変換できます。ポインターと参照の場合、結果は元のオブジェクトを参照します。データ メンバーへのポインターの場合、結果はデー​​タ メンバーへの元の (キャストされていない) ポインターと同じメンバーを参照します。参照されるオブジェクトの型によっては、結果のポインター、参照、またはデータ メンバーへのポインターを介した書き込み操作によって、未定義の動作が発生する場合があります。const_cast 演算子を使用して、定数変数の定数ステータスを直接オーバーライドすることはできません。

于 2013-09-17T05:37:34.883 に答える
6

定数オブジェクトの有無にかかわらず、誰も変更できませconst_castん。const_cast定数オブジェクトを変更することはできません。

constness を削除する場合、 の目的は、定数オブジェクトにつながるアクセス パスconst_cast(ポインターまたは参照)から constness を削除できるようにすることです。

例えば

int i = 5;
const int *p = &i;

*const_cast<int *>(p) = 10;
assert(i == 10);

上記のコードでは、ポインタを介しconst_castてオブジェクトへの変更アクセスを取得するために使用されています。オブジェクト自体は定数ではないため、その変更に問題はありません。ipi

それがの目的ですconst_cast。逆の目的にも使用できます。つまり、ポインターまたは参照型に constness を追加します。しかし、「定数オブジェクトの変更」は でできることではありませんconst_cast。定数オブジェクトは変更できません。

于 2013-09-17T06:22:27.820 に答える
2

const_castconstness をキャストするための 1 つの可能な用途は、const引数を使用しないが引数を変更しない、またはローカル コピーのみを変更する C 関数を呼び出すことです。

パーツをキャストしてからconstデータを変更すると、ほとんどの場合、未定義の動作が発生します。

于 2013-09-17T05:37:27.993 に答える