C++之const_cast的用法

C++类型转换之const_cast #include #include using namespace std; class Animal {}; class Father {}; class Son :public Father { }; /【【【const_cast类型转换】】】/ //const_cast中的类型必须是指针,引用或指向对象类型成员的指针! //作用:临时解除const属性,将具有const属性的实体进行赋值,而后具有const属性的实体仍旧具有const属性! void test01() { const int a 阅读详情

C++的四种类型转换之const_cast

前言

引用**《Effective C++ 中文版第三版》**中条款27 "尽量少做转型动作"中的一段话:

C++规则的设计目标之一是,保证“类型错误”绝对不可能发生,理论上如果你的程序很“干净”的通过编译,就表示它并不企图在任何对象上执行任何不安全、无意义、愚蠢荒谬的操作。这是一个极具价值的保证,可别草率的放弃它。

不幸的是,转型(cast)破坏了类型系统(type system),那可能导致任何种类的麻烦,有些容易辨识,有些非常隐晦。

 现实情况是类型转换在开发中无法避免,在开始探讨C++的类型转换以前我们先看下C风格的类型转换。

(T)varibale
T(variable)

 这种旧式类型转换目前依旧经常被用到,但是新式类型转换却更应该被我们去使用,这是因为:

  • 1.容易被辨识,从而更容易在程序出问题时找到问题所在

  • 2.职责划分更明细,编译器更可能在编译期找到问题。

  • 3.有更强的类型转换能力。

 目前C++提供的四种新式类型转换为

const_cast<T>()
dynamic_cast<T>()
reinterpret_cast<T>()
static_cast<T>()

 下面我们就const_cast,分别研究下其用途以及适用的使用场景

const_cast

const_cast<new type>(express)的主要用途是,移除对象的常量性,并且也是唯一具有此能力的C++风格的转型操作符

 在C++11中,const_cast可以完成以下类型转换

  • 两个可能指向同一类型的多级指针可以相互转换,而不考虑每一层上的cv性质(const and volatile)。
  • 空指针值可以转换为新类型的空指针值.

 可以看出,const_cast主要针对指针进行操作,其能力可以大概被总结为:

1、常量指针被转化成非常量的指针,并且仍然指向原来的对象;
2、常量引用被转换成非常量的引用,并且仍然指向原来的对象;

 const_cast的返回结果根据需要转换出的新类型,可以区别为:

  • 如果new type是lvalue引用,或者是函数类型的rvalue引用,则返回lvalue。
  • 如果new type是对象类型的rvalue引用,则返回xvalue。
  • 否则返回prvalue。

 以下时关于几个value的解释:

  • lvalue (Left-hand-side value)
  • rvalue (Right-hand-side value)
  • xvalue (eXpiring value)
  • prvalue (Pure rvalue)
  • glvalue (Generalized lvalue)

 For all the values, there were only two independent properties:

  • “has identity” – i.e. an address, a pointer, the user can determine whether two copies are identical, etc.use “i” represent
  • “can be moved from” – i.e. we are allowed to leave to source of a “copy” in some indeterminate, but valid state.use “m” represent.

 There are four possible composition:

  • iM: has identity and cannot be moved from (defined as lvalue)
  • im: has identity and can be moved from (defined as xvalue)
  • Im: does not have identity and can be moved from (defined as prvalue)
  • IM: doesn’t have identity and cannot be moved (他认为这种情况在 C++ 中是没有用的)

 以上出自于https://cloud.tencent.com/developer/article/1493839

 需要注意的是,const_cast中:

  1. 指向函数的指针和指向成员函数的指针不受const_cast约束。
  2. const_cast可以形成一个指向非const类型的引用或指针,它实际上引用了一个const对象,也可以形成一个指向非volatile类型的引用或指针,它实际上引用了一个volatile对象。
  3. 通过非const访问路径修改const对象并通过非volatile glvalue引用volatile对象会导致未定义的行为。

未定义行为:C++标准对此类行为没有做出明确规定.同一份代码在使用不同的编译器会有不同的效果

《C++ Primer》《Effective C++》是C++开发者必不可少的书籍,如果你想入门C++,以及想要精进C++开发技术,这两本书可以说必须要有。此外,《Linux高性能服务器编程》以及《Linux多线程服务端编程:使用muduo C++网络库》.(陈硕)》是快速提高你的linux开发能力的秘籍。在网上搜索相关资源也要花费一些力气,需要的同学可以关注公众号【程序员DeRozan】,回复**【1207】**快速免费领取~

 下面通过例子来分析const_cast的用法,C++版本为C++11

1.new type为左值引用

 将一个常量左值引用转换为一个非常量左值引用:

 int i = 3; // i is not declared const
    const int &rci = i;
    const_cast<int &>(rci) = 4; // OK: modifies i
    std::cout << "i = " << i << '\n';

 控制台输出

sh-4.4$ ./build/linux/x86_64/release/Class-convert 
i = 4

 即,如果new type为左值引用,则返回值是一个左值

2. new type为函数类型的右值引用

 如果new type的类型为函数右值引用,则const_cast的返回值为左值

void printHello(){
    cout<<"hello world"<<endl;
}

void printHello2(){
    cout<<"hello world 2"<<endl;
}

int main(){
    
    const std::reference_wrapper<void()>x = std::ref(printHello);
    // x = printHello2; //编译错误,const类型的函数右值引用
    const_cast<std::reference_wrapper<void()> &&>(x) = printHello2;  
    x();
}

3.new type为对象类型的右值引用

 将一个常量对象右值引用,转换为一个非常量的对象类型引用:

class OBJ {
    public:
    int num;
    OBJ(int i){num = i;}
    ~OBJ(){}
};


int main()
{

    const OBJ&& obj = OBJ(1);
    cout<<"obj.num="<<obj.num<<endl;

    // obj.num = 3;  //编译错误,这里是const引用

    // const_cast<OBJ&&>(obj).num = 4;// 编译错误,error: using xvalue (rvalue reference) as lvalue
    // cout << "obj.num=" << obj.num<<endl;
    
    OBJ &&obj2 = const_cast<OBJ &&>(obj);  //编译通过
    obj2.num = 3;
    cout << "obj.num=" << obj.num << endl;
}

4.指向函数的指针和指向成员函数的指针不受约束

struct type
{
    int i;

    type() : i(3) {}

    void f(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 main(){
      [[maybe_unused]] void (type::*pmf)(int) const = &type::f; // pointer to member function
    // const_cast<void(type::*)(int)>(pmf);   // compile error: const_cast does
    // not work on function pointers   
}

5.通过非const访问路径修改const对象导致未定义行为

    const int j = 3; // j is declared const
    [[maybe_unused]] int *pj = const_cast<int *>(&j);
    // *pj = 4;      // undefined behavior

6.const_cast只能用来修改指针,引用

   const int j = 3; // j is declared const
   int ppj = const_cast<int>(j); // 编译错误,invalid use of const_cast with type ‘int’, which is not a pointer, reference, nor a pointer-to-data-member type
const_cast 详解及使用场景 C++ 中最危险的类型转换之一,必须谨慎使用。在大多数情况下,有更好的替代方案。​ 的类型转换运算符。它是唯一能够移除 const 属性的 C++ 风格转换。:尽量少用,优先考虑 mutable 和更好的设计。是 C++ 中专门用于添加或移除变量的。你确切知道对象不是真正的 const。(在 const 函数中修改缓存):充分测试,确保不会导致未定义行为。转换后不会违反 const 正确性。(需要移除 const 限定符):添加注释说明为什么必须使用。有充分的理由不使用其他方法。(确认不会修改数据) 阅读详情

相关推荐

DeepSeek与豆包无缝对接:5分钟搞定智能周报自动化(附完整代码)

本文详细介绍了如何利用DeepSeek与豆包API,快速搭建一个智能周报自动化系统。通过整合豆包平台的工作流数据,并调用DeepSeek大模型进行深度分析与内容生成,该系统能在5分钟内自动抓取、分析多源信息,并生成结构清晰、富有洞察力的团队周报,显著提升工作效率。

weixin_29029995的博客 437

C++新特性06_强制转换运算符_const_cast(强制转换运算符:需要类型转换的时候使用,用于用编译器实现检测;const_cast:仅用于进行去除const 属性的转换;内存中?代表不可访问)

强制类型转换是有一定风险的,有的转换并不一定安全,如把整型数值转换成指针,把基类指针转换成派生类指针,把一种函数指针转换成另一种函数指针,把常量指针转换成非常量指针等。 1.C语言中强转的方法: int n = 1; //将n的地址赋给指针p //int* p = &n; //c语言中进行强制转换,将n作为一个地址赋给p //p是带有类型的地址 int* p = (int*)n; 当对地址为1的p进行访问的时候,会报如下错误: int main() { int n = 1

分享学习成长历程,Winter is coming! 6261

华为OD机试双机位C卷-部门人力分配 (Py/Java/C/C++/Js/Go)

华为OD机试(机考)双机位C卷 【部门人力分配】,提供C语言JavaC++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试 - 部门人力分配。

qq_45776114的博客 1843

C++const_cast 作用详解

const_cast是一种C++运算符,主要是用来去除复合类型中const和volatile属性(没有真正去除)。 我们需要注意的是:变量本身的const属性是不能去除的,要想修改变量的值,一般是去除指针(或引用)的const属性,再进行间接修改。 用法:const_cast<type>(expression) 通过const_cast运算符,也只能将const type*转换为type*,将const type&转换为type&。 也就是说源类型和目标类型除了const

weixin_44218779的博客 1万+

C++const_cast基本用法(详细讲解)

👉博__主👈:米码收割机👉技__能👈:C++/Python语言👉公众号👈:测试开发自动化【获取源码+商业合作】👉荣__誉👈:阿里云博客专家博主、51CTO技术博主👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。

测试开发自动化 5907

c++考点之const_cast用法

const_castconst_cast:作用:先来看c中不严谨的地方:在c++编译中就会报错:const_cast应用场景??不具实际意义的用法const_cast实际编程应用:整体测试代码如下: ​ 最近,身体不太好,可能是坐的时间太久了吧!调理了大概一周的时间,同时,也一周没有学习了!没啥可说的,以后多注意活动活动!进入正题: const_cast:作用: 指针或引用的转换符,用来移除变量的const或volatile限定符。 先来看c中不严谨的地方: const int ca = 30; in

guangod的博客 2095

C++const_cast和reinterpret_cast用法

使用const_cast来添加或去除const限定符。使用进行低级别的、几乎不进行任何检查的类型转换,特别是当涉及到不同类型的指针或指针与整数类型之间的转换时。在大多数情况下,建议尽量避免使用这些类型转换,因为它们可能会破坏类型安全,导致难以发现的错误。在确实需要使用时,应确保充分理解其含义和潜在风险。

Yinrtyu_的博客 472

C++之dynamic_cast、static_castconst_cast、reinterpret_cast用法和区别

简述 C++中有四个类型转换符,旨在严格限制允许的类型转换,使转换更规范。这四个转换符分别是: dynamic_cast static_cast const_cast reinterpret_cast 可以根据目的选择一个适合的运算符,而不是使用通用的类型转换。让编译器能够检查程序的行为是否与设计者想法吻合。 接下来看看每个类型转换符的用法以及它们之间的区别。 dynamic_cast ...

luoyayun361的专栏 794

const cast c语言有吗,C++const-cast与reinterpret-cast运算符的用法

C++const-cast与reinterpret-cast运算符的用法C++const_cast与reinterpret_cast运算符的用法,经常被用于表达式中的类型转换,下面是小编分享的运算符的用法,一起来看一下吧。const_cast 运算符从类中移除 const、volatile 和 __unaligned 特性。语法const_cast <type-id> (expre...

weixin_39627455的博客 220

C++ const_cast用法

const_cast是一种C++运算符,主要是用来去除复合类型中const和volatile属性(没有真正去除)。 变量本身的const属性是不能去除的,要想修改变量的值,一般是去除指针(或引用)的const属性,再进行间接修改。 用法:const_cast<type>(expression) 通过const_cast运算符,也只能将const type*转换为type...

aixirang3421的博客 890

C++ const_cast用法

const_cast是一种C++运算符,主要是用来去除复合类型中const和volatile属性(没有真正去除)。 变量本身的const属性是不能去除的,要想修改变量的值,一般是去除指针(或引用)的const属性,再进行间接修改。 用法:const_cast(expression) 通过const_cast运算符,也只能将const type*转换为type*,将const type&amp...

TH_NUM的博客 2万+

C++ 补充 & C++ 11 - C++ const_cast用法详解

const_cast用法详解 去const属性。(仅针对于指针和引用) demo 代码(一) #include <iostream> using namespace std; void demo(const char* p) { /* 对指针去掉 const char *p */ char* p1 = const_cast<char*>(p); p1[0] = 'A'; /* 直接去掉 const 修改 */ const_cast<char*>(p)[0]

weifc-wei 的博客 481

c++const_cast用法

const_cast的作用就是去掉const属性,让指针所指向的内存空间是可以被修改的,但是要注意,可能有些空间本身就是不能修改的,哪怕去掉const属性,比如常量所在的空间。 具体代码和注释如下: #include<iostream> using namespace std; //const char *p 的const修饰 让p指向的...

一路向北 2564

C++ 类型转换关键字 *_cast 】理解const_cast、reinterpret_cast、dynamic_cast和static_cast用法

c++除了能使用c语言的强制类型转换外,还新增了四种强制类型转换:static_cast、dynamic_castconst_cast、reinterpret_cast,主要运用于继承关系类间的强制转化

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 1204

C++四种强制类型转换符功能以及用法总结(dynamic_castconst_cast,static_cast,reinterpret_cast

const_cast用法const_cast (expression) 该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。 一、指向常量的指针被转化成指向非常量的指针,并且仍然指向原来的对象; 二、指向常量的引用被转换成指向非常量的引用,并且仍然指向原来的对象; Voiatile

SprintfWater的专栏 1246

C++中static_cast, dynamic_cast, const_cast用法/使用情况及区别解析

首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1部分. 隐式类型转换 又称为“标准转换”,包括以下几种情况: 1) 算术转换(Arithmetic conversion) : 在混合类型的算术表达式中, 最宽的数据类型成为目标转换类型。   int ival = 3; double dval = 3.14159;

System Architect 2万+

C++const_cast常见用法

C++提供了四个转换运算符: 1. const_cast (expression) 2. static_cast (expression) 3. reinterpret_cast (expression) 4. dynamic_cast (expression)const_cast (expression)用const_cast来去除const限定const int co

大圣编了个程 5282

C++const_cast用法

const_cast是一种C++运算符,主要是用来去除复合类型中const和volatile属性(没有真正去除)。 变量本身的const属性是不能去除的,要想修改变量的值,一般是去除指针(或引用)的const属性,再进行间接修改。 用法:const_cast(expression) 通过const_cast运算符,也只能将const type*转换为type*,将const type&amp...

sn_gis的专栏 709

c++const_cast和dynamic_cast用法

但是,使用 `const_cast` 去除 `name` 的 `const` 限定符后,就可以修改它的值。这时就可以使用 `const_cast` 去除 `getName` 方法返回值的 `const` 限定符,以便对其进行修改。在上述示例中,我们创建了一个 `Animal` 基类指针指向 `Dog` 对象,并使用 `dynamic_cast` 将其转换为 `Dog` 类型的指针。- `const_cast` 用于去除指针或引用的 `const` 或 `volatile` 限定符,以便对其进行修改。

weixin_37841024的博客 915
上一篇: emplace_back与push_back异同
下一篇: C++类型转换之static_cast
Michael.Scofield
博客等级 码龄7年 296粉丝 200原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Michael.Scofield

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值