C++类型转化分析:强制转换->const_cast转换

来源:互联网 发布:淘宝哪家茶叶店好 编辑:程序博客网 时间:2024/06/06 01:26

const_cast转换
    该转换的作用是移除变量的const属性或者volatile属性
移除const限定:
    对于const变量我们不能修改它,但是如果我们非要修改它该怎么办呢?嗯那我们直接使用const_cast转换就可以了。但是需要注意的是const_cast转换符不该用在数据对象上,因为这样的转换得到的两个变量/对象没有相关性,只有用于指针或者引用,让变量指向同一个地址才是最终的解决方案。例子:
const int constan=10;
const int* const_p=&constan;
int* temp=const_cast<int*>(const_p);
*temp=7;//好了,constan的值不是10了现在变成7了
C++对于指针转换是任意的,它不会做类型检查,任何指针之间都可以进行转换,因此const_cast可以使用传统的方法来转换:
const int constant=21;
const int* const_p=&constant;
int* temp=(int*)(const_p);
或者
const int constant=20;
int* temp=(int*)(&constant);
但是请记住:这里改变的值不是constant的值,只是将constant的值去除const属性后获得的值,在C++中,const就是const,不管怎么操作,它的值就是不变。
未定义就是说这个标准在C++中没有明确的规定,由编译器来绝对怎么处理,对于未定义行为,我们能做的就是避免这样的语句出现,但是有一点请记住:绝对不对const数据进行重新赋值的操作。
如果不想修改const的值,那我们为什么要去除const属性呢?常见的使用情况会是下面的情况:
我们有一个函数,该函数的参数不是const类型的,但是传递给我们的参数是const类型的,我们也知道这个函数是不会对参数进行修改的,所以我们就会选择使用const_cast去除const限定符号,以便这个函数可以接收这个参数。
例子一:
#include <iostream>
#include <string>
using namespace std;
void myprint(int* val,string seperator="\n"){
    cout<<val<<seperator;
}
int main(){
    const int constant=20;
    myprint(const_cast<int*>(&constant));
    return 0;
}
const_cast转换虽然能去除const变量的属性,但是合格的编程开发人员应该明白:使用const_cast去除const限定的绝对目的不是为了修改它的内容,只是处于无奈我们想使用它的值
例子:
struct S{
    int value;
    void foo(){
        cout<<"void foo()"<<endl;
    }
    void foo() const{
        cout<<"void foo() const"<<endl;
    }
    void f() const{
        foo();//打印foo()const
        (const_cast<S*>(this))->foo();//打印非const版的foo()
    }
}

再来个详细的例子,这个例子可以说明const_cast的本质:
#include<iostream>
using namespace std;
int   main(){
    const int i=11;
    const int *pi=&i;
    int *pi2=const_cast <int*>(pi);
    *pi2=90;
    cout<<&i<<'\t'<<i<<endl;
    cout<<pi<<'\t'<<*pi<<endl;
    cout<<pi2<<'\t'<<*pi2<<endl;
    return 0;

输出是:
0xbfe8b0b4    11
0xbfe8b0b4    90
0xbfe8b0b4    90
呵呵数据地址是一样的,但是数据的值是不一样的!

另外const指针和const数据有时候可能会混淆,我们总结下:
char* p="www.jiaojiaoni.com";//非const指针,指针可变;非const数据,数据可变
const char* p="hello";//非const指针,指针可变;const数据,数据不可变
char* const p="hell0";//const指针,指针不可变;非const数据,数据可变
const char* const p="www.jiaojiaoni.com"//指针和数据都是const的,都不可变

综上所述
const_cast<type_id> (expression) 
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。 
一、常量指针被转化成非常量指针,并且仍然指向原来的对象; 
二、常量引用被转换成非常量引用,并且仍然指向原来的对象; 
三、常量对象被转换成非常量对象。  
四、type_id 必须为指针或引用 
例子:
class B{  
public:  
    int m_iNum;  
    B():m_iNum(50) {}  
};
void foo(){
    const B *b1 = new B();
    //b1->m_iNum = 100; //compile error  
    B *b2 = const_cast<B*>(b1);
    b2->m_iNum = 200;
    cout<<"b1: "<< b1->m_iNum <<endl;
    cout<<"b2: "<< b2->m_iNum <<endl;
    cout<<endl;
    const B b3;
    //b3.m_iNum = 100; //compile error
    B b4 = const_cast<B&>(b3);//b4 is another object
    b4.m_iNum = 200;
    cout<<"b3: "<<b3.m_iNum <<endl;
    cout<<"b4: "<<b4.m_iNum <<endl;
    cout<<endl;
    const B b5;
    //b5.m_iNum = 100; //compile error
    B &b6 = const_cast<B&>(b5);
    b6.m_iNum = 200;  
    cout<<"b5: "<<b5.m_iNum <<endl;  
    cout<<"b6: "<<b6.m_iNum <<endl;  
    cout << endl;  
    // force to convert   
    const int x = 50;  
    int* y = (int *)(&x);// same address, but the content is different  
    *y = 200;  
    cout << "x: "<<x<<" address: "<<&x<<endl;  
    cout << "*y: "<<*y<<" address: "<<y<<endl;  
    cout<<endl;  
    // int  
    const int xx = 50;  
    int* yy = const_cast<int *> (&xx);// same address, but the content is different  
    *yy = 200;  
    cout << "xx: "<<xx<<" address: "<<&xx<<endl;  
    cout << "*yy: "<<*yy<<" address: "<<yy<<endl;  
    cout<<endl;
    const int xxx = 50;  
    int yyy = const_cast<int&> (xxx);// another int  
    yyy = 200;
    cout << "xxx: "<<xxx<<" address: "<<&xxx<<endl;  
    cout << "yyy: "<<yyy<<" address: "<<&yyy<<endl;  
}
int main(int argc, char* argv[]){  
    foo();  
    return 0;  
}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 拔牙后肿的厉害怎么办 拨牙之后脸肿怎么办 种牙之后脸肿了怎么办 鼻子放假体老了怎么办 鸡蛋吃多过敏了怎么办 想把衣服换颜色怎么办 衣服用84洗坏了怎么办 衣服用84洗花了怎么办 衣服用84洗黄了怎么办 白色衣服用84漂黄了怎么办 84把衣服泡黄了怎么办 84把衣服洗花了怎么办 衣服用84洗掉色怎么办 被84褪色的衣服怎么办 衣服被84烧红了怎么办 84溅到衣服上边怎么办 84把衣服泡花了怎么办 衣服颜色洗旧了怎么办 蒙版画笔用不了怎么办 眼睛小血管破裂出血怎么办 雅漾喷头坏了怎么办 一夜都是浅睡眠怎么办 注塑机合不了膜怎么办 吸了塑料烧焦味怎么办 热熔的管漏水怎么办 45岁了月经不来怎么办 吃了芒果身上痒怎么办 10个月宝宝上火怎么办 1个月的宝宝上火怎么办 2个月的婴儿上火怎么办 1岁宝宝不吃奶粉怎么办 奶水不够宝宝又不吃奶瓶怎么办 13岁脸上长粉刺怎么办 脸敷面膜过敏了怎么办 婴儿面膜是假的怎么办 一贴面膜就过敏怎么办 一敷面膜就过敏怎么办 敷了面膜后过敏怎么办 脸做面膜过敏了怎么办 二十几年的疤痕怎么办 三星c5听筒坏了怎么办