const_cast也是一个强制类型转换操作符。《C++ Primer》中是这样描述它的:

1.将转换掉表达式的const性质。

2.只有使用const_cast才能将const性质性质转化掉。试图使用其他三种形式的强制转换都会导致编译时的错误。(添加const还可以用其他转换符,如static_const

3.除了添加const或删除const特性,使用const_cast符来执行其他任何类型的转换都会引起编译错误。(volatile限定符也包括,不过我不怎么了解,本文主要说const)

对于第一点,转换掉表达式的const性质,意思是可以改变const对象的值了吗?一开始我的确是这样子认为的,于是我敲出了如下的代码:

int main()
{
const int constant = ;
const int* const_p = &constant;
int* modifier = const_cast<int*>(const_p);
*modifier = ;
cout<< "constant: "<<constant<<endl;
cout<<"*modifier: "<<*modifier<<endl;
system("pause");
}

然而程序并没有像预想的那样输出两个3,运行结果是这样的:

看来C++还是很厚道的,对声明为const的变量来说,常量就是常量,任你各种转化,常量的值就是不会变。这是C++的一个承诺。

那既然const变量的值是肯定不会发生变化的,还需要这个const_cast类型转化有何用?这就引出了const_cast的最常用用法:

如果有一个函数,它的形参是non-const类型变量,而且函数不会对实参的值进行改动,这时我们可以使用类型为const的变量来调用函数,此时const_cast就派上用场了。

例如:

void InputInt(int * num)
{
cout<<*num<<endl;
}
int main()
{
const int constant = ;
//InputInt(constant); //error C2664: “InputInt”: 不能将参数 1 从“const int”转换为“int *”
InputInt(const_cast<int*>(&constant));
system("pause");
}

 除此之外,还有另外一种情况const指针能够派上用场。如果我们定义了一个非const的变量,却使用了一个指向const值的指针来指向它(这不是没事找事嘛),在程序的某处我们想改变这个变量的值了,但手头只持有指针,这是const_cast就可以用到了:

int main()
{
int constant = ;
const int* const_p = &constant;
int* modifier = const_cast<int*>(const_p);
*modifier = ;
cout<< "constant: "<<constant<<endl;
cout<<"*modifier: "<<*modifier<<endl; system("pause");
}

 总结一下上文:const_cast绝对不是为了改变const变量的值而设计的!

        在函数参数的传递上const_cast的作用才显现出来。

>>>>>>>>>>>>>>>>>> >>>分割线>>>>>>>>>>>>>>>>>>>>>>>>>

const_cast中的未定义行为

 上面的第一段程序,输出变量constant与*modefier的地址后....

int main()
{
const int constant = ;
const int* const_p = &constant;
int* modifier = const_cast<int*>(const_p);
*modifier = ;
cout<< "constant: "<<constant<<" adderss: "<< &constant <<endl;
cout<<"*modifier: "<<*modifier<<" adderss: " << modifier<<endl; system("pause");
}

运行结果:

它们的地址是一样的,值却不同。具体原因我还是不大清除。在另外一些博客中看到, *modifier = 3; 这种操作属于一种“未定义行为”,也即是说操作结果C++并没有明确地定义,结果是怎样的完全由编译器的心情决定。对于未定义的行为,我们只能避免之。

关于const_cast是否安全的讨论

逛了一些网站,大致有如下观点:

const_cast is safe only if you're casting a variable that was originally non-const. For example, if you have a function that takes a parameter of a const char *, and you pass in a modifiable char *, it's safe to const_cast that parameter back to a char * and modify it. However, if the original variable was in fact const, then using const_cast will result in undefined behavior.

也即是上文中所说的const_cast的二种适用情况。
I would rather use static cast for the adding constness: static_cast<const sample*>(this). When I'm reading const_cast it means that the code is doing something potentially dangerous, so i try to avoid it's use when possible.

也有人认为const_cast本身就给潜在危险带来可能,所以还是尽可能不用它了。
当需要给变量添加const属性时,使用更为安全的static_cast来代替const_cast。 这里附上讨论链接。const_cast是否安全?

C++强制类型转换操作符 const_cast的更多相关文章

  1. C++强制类型转换操作符 static_cast

    static_cast是一个强制类型转换操作符.强制类型转换,也称为显式转换,C++中强制类型转换操作符有static_cast.dynamic_cast.const_cast.reinterpert ...

  2. C++强制类型转换操作符 dynamic_cast

    dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用. >>>>>>>>>>>编译器的RTTI设 ...

  3. c++强制类型转换(static_cast,const_cast,dynamic_cast,reinterpret_cast)

    static_cast <typeid>(exdlvssion) static_cast 很像 C 语言中的旧式类型转换.它能进行基础类型之间的转换,也能将带有可被单参调用的构造函数或用户 ...

  4. c++强制类型转换:dynamic_cast、const_cast 、static_cast、reinterpret_cast

    c++强制类型转换:dynamic_cast.const_cast .static_cast.reinterpret_cast 博客分类: C/C++ CC++C#编程数据结构  dynamic_ca ...

  5. C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast

    1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2 ...

  6. 四种强制类型转换的总结(const_cast、static_cast、dynamic_cast、reinterpreter_cast)

    四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast) 转载 2011年10月03日 23:59:05 标签: stru ...

  7. C++里的强制类型转换符reinterpret_cast、static_cast 、dynamic_cast、const_cast 区别

    C 风格(C-style)强制转型如下: (T) exdivssion // cast exdivssion to be of type T 函数风格(Function-style)强制转型使用这样的 ...

  8. 类型转换操作符static_cast、const_cast、dynamic_cast、reinterpret_cast

    一.static_cast 对于类型转换,我们常常这么做: (type) expression 引进了static_cast类型转换操作符后,我们只需这样做: static_cast<type& ...

  9. 《C#高效编程》读书笔记03-推荐使用is或as操作符而不是强制类型转换

    在日常编码中,很多时候都要编写接受object作为参数的方法,接下来是将这些object转型成特定类型,要么类,要么接口.这时我们有两种选择,使用as操作符,或者使用强制类型转换. 正确的做法是,尽可 ...

随机推荐

  1. HTML 学习笔记 CSS3 (2D转换)

    2.scaleX(<number>) : 使用 [sx,1] 缩放矢量执行缩放操作,sx为所需参数.scaleX表示元素只在X轴(水平方向)缩放元素,他的默认值是(1,1),其基点一样是在 ...

  2. 配置Tomcat使用Redis作为session管理

    1. 在 tomcat/lib 中增加以下jar包 commons-pool2-.jar jedis-.jar tomcat-redis-session-manager-.jar 2. 修改tomca ...

  3. Number of Digit One

    Given an integer n, count the total number of digit 1 appearing in all non-negative integers less th ...

  4. 解决nf_conntrack: table full, dropping packet问题

    " > /proc/sys/net/nf_conntrack_max iptables -t raw -A PREROUTING -p tcp -m tcp --dport -j NO ...

  5. checkboxlist 下拉框多选功能 ,模拟dropdownlist带复选框效果

    前台代码 01.<html xmlns="http://www.w3.org/1999/xhtml"> 02.<head runat="server&q ...

  6. 【活动】写#听云#原创博文 赢取iPhone 6超级大奖

    移动应用的使用量和重要性与日俱增,用户体验的要求也越来越高.与桌面程序相比,移动应用耗电小,速度慢,但手机用户却希望享受到与桌面程序同样的加载速度.那么如何发现移动应用的性能黑洞,优化移动应用性能,这 ...

  7. Java序列化中的SerialVersionUid

    版权声明:本文为博主fbysss原创文章,转载请注明出处 作者:fbysssmsn:jameslastchina@hotmail.com  blog:blog.csdn.NET/fbysss声明:本文 ...

  8. python学习笔记整理——dictView [未整理]

    Dictionary view objects简介 The objects returned by dict.viewkeys(), dict.viewvalues() and dict.viewit ...

  9. 0929mysql 用户管理和权限设置

    转来自http://www.cnblogs.com/fslnet/p/3143344.html 用户管理 mysql>use mysql; 查看 mysql> select host,us ...

  10. MyEclipse下Maven的安装配置

    Maven常用命令: •mvn archetype:generate :创建 Maven 项目 •mvn compile :编译源代码 •mvn test-compile :编译测试代码 •mvn t ...