天天看點

C++新式轉型之const_cast

将對象的常量性移除,即去掉const限定。

int main()
{
    const int c = ;
#if 0
    int &cc = c;//error: 将int&類型的引用綁定到const int 時,限定符被丢棄
    int *pc = &c;//error: const int * 不能初始化int *實體
#endif

#if 1
    int & rc = const_cast<int &>(c);
    rc = ;
    cout << "after cast" << endl;

    //位址相同
    cout << &c << endl;
    cout <<& rc << endl;
    //值不相同
    cout << c << endl;
    cout << rc << endl;
#endif
    system("pause");
    return ;
}
           

上面示例有個讓我困惑的地方,用

const_cast<>

将一個const值綁定到一個非const引用上,并試圖通過這個非const引用去修改原來的值是一個

Undefined Reference

。事實上,應該遵循這樣的原則:使用

const_cast

去除

const

限定的目的絕不是為了修改它的内容,隻是出于無奈。

我們來看看兩種使用

const_cast

的地方:

第一種

我們可能調用了一個參數不是const的函數,而我們要傳進去的實際參數确實const的,但是我們知道這個函數是不會對參數做修改的。于是我們就需要使用const_cast去除const限定,以便函數能夠接受這個實際參數。
void print(int * val)
{
    cout << *val << endl;
}

int main()
{
    const int c = ;
    //print(&c);//error: const int*類型的實參和int*類型的形參不相容。
    print(const_cast<int *>(&c));//OK 列印2
    system("pause");
    return ;
}
           

與C庫或一些老的(不好的)第三方庫并存。比如 strtoul,它的形參類型是 char* 和 char**,但它并不修改所指的字元,使用它時通常需要 const_cast。

第二種

在const成員函數中使用。

const成員函數,在調用時傳入一個const指針,表示我不可以通過該函數修改成員變量的值。不過這種說法并不準确:

#include <iostream>
struct type {
    type() :i() {}
    void m1(int v) const {
        // this->i = v;                 // compile error: this is a pointer to const
        const_cast<type*>(this)->i = v; // OK as long as the type object isn't const
    }
    int i;
};
int main()
{
    //當const type t;
    //t.m1(4);//這是未定義行為
    //
    type t; // note, if this is const type t;, then t.m1(4); is UB
    t.m1();
    std::cout << "type::i = " << t.i << '\n';
    system("pause");
    return ;
}
           

參考

http://www.cnblogs.com/ider/archive/2011/07/22/cpp_cast_operator_part2.html

http://en.cppreference.com/w/cpp/language/const_cast

https://www.zhihu.com/question/19772701