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. HOJ 2713 Matrix1

    Matrix1 My Tags   (Edit)   Source : Classical Problem   Time limit : 5 sec   Memory limit : 64 M Sub ...

  2. k-d tree 学习笔记

    以下是一些奇怪的链接有兴趣的可以看看: https://blog.sengxian.com/algorithms/k-dimensional-tree http://zgjkt.blog.uoj.ac ...

  3. mysql连接数设置操作(Too many connections)

    mysql在使用过程中,发现连接数超了~~~~ [root@linux-node1 ~]# mysql -u glance -h 192.168.1.17 -pEnter password: ERRO ...

  4. c#中序列化

    序列化(Serialization)是.NET平台的特性之一.1.为什么要序列化:首先你应该明白系列化的目的就不难理解他了.系列化的目的就是能在网络上传输对象,否则就无法实现面向对象的分布式计算.比如 ...

  5. web框架学习列表

    转载自鲁塔弗的博客,原文网址:http://lutaf.com/148.htm web framework层出不穷,特别是ruby/python,各有10+个,php/java也是一大堆 根据我自己的 ...

  6. PHP用户注册邮箱验证激活帐号

    我们在很多网站注册会员时,注册完成后,系统会自动向用户的邮箱发送一封邮件,这封邮件的内容就是一个URL链接,用户需要点击打开这个链接才能激活之前在该网站注册的帐号.激活成功后才能正常使用会员功能. 本 ...

  7. MIPAV - Talairach ACPC transform

    源地址:http://blog.sina.com.cn/s/blog_64cfe24f0100h358.html 1.打开MIPAV软件,File>open image from disk> ...

  8. 在linux下运行java工程

    在linux 服务器上运行JAVA工程需注意.1: 在linux 上: /etc/profile  设置classpath 配置正确的jar 路径.2:  把本地JAVA工程做成一个jar包.如:1. ...

  9. mac里git项目删除.DS_Store文件

    用mac开发项目,每次提交文件时都生成修改文件的.DS_Store文件,提交时会不会觉得比较烦?别急,下面给出解决方案.我们需要用到.gitignore文件去配置Git目录中需要忽略的文件. .git ...

  10. HDU2389-Rain on your Parade-二分图匹配-ISAP

    裸二分图匹配 /*--------------------------------------------------------------------------------------*/ #i ...