質問

あまり情報が見つかりません 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 にポインターまたは参照を渡したいが、確実にオブジェクトを変更しない場合です。実際には何も変わらないことを信頼して、ポインターを 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 について見つけることができる情報。からの引用 Google で 2 回目のヒット:

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;
};

まず型に const を追加します this を指す場合、その const バージョンを呼び出します getT, 次に、戻り値の型から const を削除します。これは有効です。 t 非定数でなければなりません (それ以外の場合は、 getT 電話はできなかったでしょう)。これは、関数本体が大きく、冗長なコードを避けたい場合に非常に役立ちます。

簡単に言うと「いいえ、安全ではありません」です。

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

あなたがキャストしているとき、あなたが本質的に言っているのは、「私はコンパイラーが知らないことを知っている」ということです。 const_castの場合、あなたが言っているのは、「この方法では、コンクロッドのリファレンスまたはポインターを取り入れていても、パラメーターを渡すことはないことを知っています。」

したがって、キャストを使用する際に自分が知っていると主張していることを実際に知っているのであれば、それを使用しても問題ありません。

コンパイラが const と判断したものを変更し始めると、スレッド セーフの可能性が台無しになります。

#include <iostream>
using namespace std;

void f(int* p) {
  cout << *p << endl;
}

int main(void) {
  const int a = 10;
  const int* b = &a;

  // Function f() expects int*, not const int*
  //   f(b);
  int* c = const_cast<int*>(b);
  f(c);

  // Lvalue is const
  //  *b = 20;

  // Undefined behavior
  //  *c = 30;

  int a1 = 40;
  const int* b1 = &a1;
  int* c1 = const_cast<int*>(b1);

  // Integer a1, the object referred to by c1, has
  // not been declared const
  *c1 = 50;

  return 0;
}

ソース: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2F language%2Fref%2Fkeyword_const_cast.htm

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top