zoukankan      html  css  js  c++  java
  • const_cast

    ---恢复内容开始---

     参考博客:https://www.cnblogs.com/QG-whz/p/4513136.html

    const_cast是一个基于C语言编程开发的运算方法,

    其主要作用是修改类型的const或volatile属性。使用该运算方法可以返回一个指向非常量的指针(或引用)指向b1,

            就可以通过该指针(或引用)对它的数据成员任意改变。

    用法

    :const_cast<type_id> (expression)
    该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
    一、常量指针被转化成非常量的指针,并且仍然指向原来的对象;
    二、常量引用被转换成非常量的引用,并且仍然指向原来的对象;
    三、const_cast一般用于修改底指针。如const char *p形式。
    class B
    {
    public:
        B() { }
    public:
        int m_iNum;
    };
    void foo()
    {
        const B b1;
        //b1.m_iNum = 100; //compile error
        // 可以做如下转换,体现出转换为指针类型
        B *b2 = const_cast<B*>(&b1);
        // 或者左侧也可以用引用类型,如果对b2或b3的数据成员做改变,就是对b1的值在做改变
        B &b3 = const_cast<B&>(b1);
        b2->m_iNum = 200;    //fine
        b3.m_iNum = 300;    //fine
    }
    int main( int argc, char * argv[] )
    {
        foo();
        return 0;
    }

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

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

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

    3.除了添加const或删除const特性,使用const_cast符来执行其他任何类型的转换都会引起编译错误。

    int main()
    {
        const int constant = 26;
        const int* const_p = &constant;
        int* modifier = const_cast<int*>(const_p);
        *modifier = 3;
        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 = 21;
        //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 = 26;
        const int* const_p = &constant;
        int* modifier = const_cast<int*>(const_p);
        *modifier = 3;
        cout<< "constant:  "<<constant<<endl;
        cout<<"*modifier:  "<<*modifier<<endl;
    
        system("pause");
    }

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

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

    const_cast中的未定义行为

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

    #include <QCoreApplication>
    
    #include <iostream>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        const int constant = 26;
        const int* const_p = &constant;
        int* modifier = const_cast<int*>(const_p);
        *modifier = 3;
        cout<< "constant:  "<<constant<<"  adderss:  "<< &constant <<endl;
        cout<<"*modifier:  "<<*modifier<<"  adderss:  " << modifier<<endl;
    
    
        return a.exec();
    }

    输出:

    constant:  26  adderss:  0x65fe8c
    *modifier:  3  adderss:  0x65fe8c

    它们的地址是一样的,值却不同。具体原因我还是不大清除。在另外一些博客中看到, *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是否安全?
    复制代码

    ---恢复内容结束---

  • 相关阅读:
    ORACLE函数介绍
    msdn的javascript文章转载
    baidu的高级搜索命令
    周杰伦 青花瓷 蒲公英的约定 我不配 彩虹 歌词和下载
    谷歌百度相争 新浪渔翁得利
    tomcat+jsp web运行环境搭建
    C#2008与.NET 3.5 高级程序设计读书笔记(24) LINQ API编程
    C#2008与.NET 3.5 高级程序设计读书笔记(16) 类型反射、晚期绑定和基于特性的编程
    C#2008与.NET 3.5 高级程序设计读书笔记(15) .NET程序集入门
    C#2008与.NET 3.5 高级程序设计读书笔记(25) WCF
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/10851245.html
Copyright © 2011-2022 走看看