天天看点

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