に関する情報があまり見つかりませんconst_cast
。私が(Stack Overflowで)見つけた唯一の情報は次のとおりです。
は
const_cast<>()
、変数のconst(ness)(またはvolatile-ness)を追加/削除するために使用されます。
これは私を緊張させます。const_cast
予期しない動作を引き起こす可能性がありますか?もしそうなら、何ですか?
または、いつ使用しても大丈夫const_cast
ですか?
に関する情報があまり見つかりませんconst_cast
。私が(Stack Overflowで)見つけた唯一の情報は次のとおりです。
は
const_cast<>()
、変数のconst(ness)(またはvolatile-ness)を追加/削除するために使用されます。
これは私を緊張させます。const_cast
予期しない動作を引き起こす可能性がありますか?もしそうなら、何ですか?
または、いつ使用しても大丈夫const_cast
ですか?
const_cast
元々非であった変数をキャストしている場合にのみ安全ですconst
。たとえば、のパラメータを受け取る関数がありconst char *
、変更可能なを渡した場合、そのパラメータをに戻して変更してもchar *
安全です。ただし、元の変数が実際にあった場合、を使用すると未定義の動作になります。const_cast
char *
const
const_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
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];
}
};
これが const_cast に関する唯一の情報だとは信じがたいです。2番目のGoogleヒットからの引用:
const として明示的に宣言されたオブジェクトの constness をキャストし、それを変更しようとすると、結果は未定義になります。
ただし、const として明示的に宣言されていないオブジェクトの constness をキャストする場合は、安全に変更できます。
アダムの言うこと。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
呼ばれました)。これは、関数本体が大きく、冗長なコードを避けたい場合に非常に便利です。
簡単に言えばノーです。安全ではありません。
長い答えは、それを使用するのに十分な知識があれば安全であるということです。
キャストしているとき、本質的に言っているのは、「コンパイラーが知らないことを知っている」ということです。const_cast の場合、「このメソッドは非 const 参照またはポインターを受け取りますが、渡すパラメーターが変更されないことはわかっています。」
したがって、キャストを使用して知っていると主張していることを実際に知っている場合は、それを使用しても問題ありません。
コンパイラが const と考えていたものを変更し始めると、スレッド セーフの可能性が失われます。