95

に関する情報があまり見つかりませんconst_cast。私が(Stack Overflowで)見つけた唯一の情報は次のとおりです。

const_cast<>()、変数のconst(ness)(またはvolatile-ness)を追加/削除するために使用されます。

これは私を緊張させます。const_cast予期しない動作を引き起こす可能性がありますか?もしそうなら、何ですか?

または、いつ使用しても大丈夫const_castですか?

4

6 に答える 6

93

const_cast元々非であった変数をキャストしている場合にのみ安全ですconst。たとえば、のパラメータを受け取る関数がありconst char *、変更可能なを渡した場合、そのパラメータをに戻して変更してもchar *安全です。ただし、元の変数が実際にあった場合、を使用すると未定義の動作になります。const_castchar *constconst_cast

void func(const char *param, size_t sz, bool modify)
{
    if(modify)
        strncpy(const_cast<char *>(param), sz, "new string");
    printf("param: %s\n", param);
}

...

char buffer[16];
const char *unmodifiable = "string constant";
func(buffer, sizeof(buffer), true);  // OK
func(unmodifiable, strlen(unmodifiable), false); // OK
func(unmodifiable, strlen(unmodifiable), true);  // UNDEFINED BEHAVIOR
于 2008-12-10T21:04:30.760 に答える
36

const_cast が安全で便利な 2 つの状況を考えることができます (他にも有効なケースがあるかもしれません)。

1 つは、const インスタンス、参照、またはポインターがあり、const に正しくない API へのポインターまたは参照を渡したいが、CERTAIN がオブジェクトを変更しない場合です。ポインターを const_cast して API に渡すと、実際には何も変更されないことを信頼できます。例えば:

void log(char* text);   // Won't change text -- just const-incorrect

void my_func(const std::string& message)
{
    log(const_cast<char*>(&message.c_str()));
}

もう 1 つは、'mutable' を実装していない古いコンパイラを使用していて、論理的に const であるがビットごとの const ではないクラスを作成したい場合です。const メソッド内で「this」を const_cast し、クラスのメンバーを変更できます。

class MyClass
{
    char cached_data[10000]; // should be mutable
    bool cache_dirty;        // should also be mutable

  public:

    char getData(int index) const
    {
        if (cache_dirty)
        {
          MyClass* thisptr = const_cast<MyClass*>(this);
          update_cache(thisptr->cached_data);
        }
        return cached_data[index];
    }
};
于 2008-12-10T21:25:59.263 に答える
25

これが const_cast に関する唯一の情報だとは信じがたいです。2番目のGoogleヒットからの引用:

const として明示的に宣言されたオブジェクトの constness をキャストし、それを変更しようとすると、結果は未定義になります。

ただし、const として明示的に宣言されていないオブジェクトの constness をキャストする場合は、安全に変更できます。

于 2008-12-10T21:10:29.310 に答える
13

アダムの言うこと。const_cast が役立つ別の例:

struct sample {
    T& getT() { 
        return const_cast<T&>(static_cast<const sample*>(this)->getT()); 
    }

    const T& getT() const { 
       /* possibly much code here */
       return t; 
    }

    T t;
};

this最初に const を指す型に追加し、次に const バージョンのを呼び出し、次にgetT戻り値の型から const を削除しtます。getT呼ばれました)。これは、関数本体が大きく、冗長なコードを避けたい場合に非常に便利です。

于 2008-12-10T21:17:48.983 に答える
10

簡単に言えばノーです。安全ではありません。

長い答えは、それを使用するのに十分な知識があれば安全であるということです。

キャストしているとき、本質的に言っているのは、「コンパイラーが知らないことを知っている」ということです。const_cast の場合、「このメソッドは非 const 参照またはポインターを受け取りますが、渡すパラメーターが変更されないことはわかっています。」

したがって、キャストを使用して知っていると主張していることを実際に知っている場合は、それを使用しても問題ありません。

于 2008-12-10T22:39:53.047 に答える
3

コンパイラが const と考えていたものを変更し始めると、スレッド セーフの可能性が失われます。

于 2008-12-10T21:16:37.100 に答える