当前位置: 首页 > news >正文

关于类型转换的细节(隐式类型转换的临时变量和理解const权限)

文章目录

  • 前言
  • 类型转换的细节
    • 1. 类型转换的临时变量
    • 细节二:const与指针

前言

关于类型转换的细节,这里小编和大家探讨两个方面:

  1. 关于类型转化的临时变量的问题
  2. const关键字的权限问题 — 即修改权限。小编或通过一道例题(配图)来带大家了解这个权限问题!

类型转换的细节

还有一些常见的问题(例如整型提升的问题)小编这里不做介绍,主要介绍下面两种:

1. 类型转换的临时变量

为什么说类型转换细节呢?来看下面的程序:

#include<iostram>
using namespace std;
int main()
{int a = 0;double& ref = a;return 0;
}

又或者是这样:

#include<iostram>
using namespace std;
int main()
{int a = 0;double& ref = (double)a;return 0;
}

上面代码有问题吗?当然有问题,VS2022编译器是会报错的……

在这里插入图片描述

这是什么原因导致的呢?

  • 实际上一个类型转换的过程应该是这样的:
    在这里插入图片描述
    临时变量tmp是具有常性的(可读不可写),所以是无法如此被引用的。所以只能通过另外的方法,得到它们的引用。

注:关于这个观点证明,借助右值引用的移动语义就可以完成验证。

#include<iostram>
using namespace std;
int main()
{int a = 0;const double& ref = a;return 0;
}
  • 一定是const type&才可以。一定要注意这个细节。
  • 关于对于这个问题,编译器在对自定义类型的时候都会做出一定的优化

那么对于这些场景就会产生许多问题,例:

namespace test
{class A{public:A():_a(1){}virtual void set(int val){_a = val;}int _a;};class B :public A{public:B():_b(0){}virtual void set(int val){static_cast<A>(*this).set(val); //很有问题的写法//A::set(val);}int _b;};void Test1(){B bb;bb.set(120);cout << bb._a << endl;}
}

我们想要在B类的set中调用A类(父类)的set,但是这样的类型转换是不会起到任何效果的,还记得刚刚所讨论的吗?类型转换会产生临时变量临时变量是不会改变原来的值的。这些都是隐式类型转换的细节。

包括有时候对指针进行了强制类型转换过后:

int a = 10;
int* ptr = &a;
char* c = ++(char*)ptr;

这样的类型转换都是不会达到如愿的结果的!!!

细节二:const与指针

在说明这个问题之前,我们先声明:

  • 权限可以缩小
  • 权限可以平移
  • 权限不能放大

来看下面这个例子,来理解一些关于权限问题

const int* const ptr1 = 0;
const int* ptr2 = 1;
int* const ptr3 = 2;

对于上面三个语句,以我们对于const的理解:

  1. ptr1ptr1指向的内容都不可以更改
  2. ptr2指向的内容不可以更改
  3. ptr3本身不能更改

我们都知道:const T* 是不允许转换为T*。(除非使用const_cast去掉const属性)这些都是我们所了解的,那么如果加上二级指针呢?
例如下面代码:

const int d = 0;   
const int* c = &d;   //1
int e = 1;   
int *f = &e;        //2
int **b = &f;       //3
const int **a = b; //4
*a = c;             //5

对于上面所标识的5条语句,你觉得有没有错误的呢?

编译器会告诉你,语句4是错误的!!
在这里插入图片描述
这个时候就要问为什么

我们来分析一下:

  1. 首先我们来看,这个赋值的过程,来看是否有权限的放大问题。首先,创建一个const变量d,然后一个创建了一个const int*的指针指向这个变量,没有问题,是一个权限的平移。然后略过创建e,f,b过程,来到const int **a = b语句,从权限来看,这似乎是没有问题的,a是一个指针的指针,对于a指向的指针的指向内容一个const内容,而b指针指向的指针的指向内容不是一个const内容,似乎看来这是一个权限的缩小。指向是有潜在有问题的!

  2. 我们用b初始化了a,那么修改*a,就是修改*b,经过了语句5,此时*a*b都指向了c。发现了吗?c是一个const int* 类型,而b是一个int* 类型。没错,这里发生了什么?间接地使const int*类型转换为了int*类型(违背了上面的原则!)。即使是我们去掉了语句5,结果仍然不会通过!
    在这里插入图片描述

  3. 下面我们作图来解释关系
    在这里插入图片描述

所以:int ** 不能转换为 const int ** !!!这是为了以绝后患。如果在const int **声明的时候做如下声明:const int* const *a = b 那么语句*a = c就不会通过编译,就不会出现报错的问题了!
在这里插入图片描述
那么有了以上的一些储备,我们来看如下的代码:

class A{};void f(const A** p){}
void g(const A* const *p){}
void k(const A*& p){}int main()
{const A* ca = new A;A* a = new A;A** p = &a;k(ca); // 1f(p);  // 2g(p);  // 3// ……return 0;
}

在这个代码中,你能看出来语句1,2,3哪些有问题,为什么呢?

还有什么经验细节,都欢迎大家分享!

完。

http://www.xdnf.cn/news/311527.html

相关文章:

  • YOLOv8的Python基础--函数篇
  • 【Java】不同变量类型的线程安全、不同修饰符下的继承
  • SCINet 训练代码修改
  • Windows系统升级Nodejs版本
  • Pulse Control LSI vs CPU for motion control
  • 基于STM32、HAL库的TSC2007IPWR触摸屏控制器驱动程序设计
  • MD2card + Deepseek 王炸组合 一键制作小红书知识卡片
  • hybird接口
  • Flutter 合并 ‘dot-shorthands‘ 语法糖,Dart 开始支持交叉编译
  • 左顾右盼-第16届蓝桥第5次STEMA测评Scratch真题第2题
  • java每日精进 5.06【框架之功能权限】
  • 永磁同步电机控制算法-反馈线性化直接转矩控制
  • vue项目生产环境中,nginx的配置
  • 在c++中老是碰到string,这是什么意思?
  • AI大模型驱动的智能座舱研发体系重构
  • 【Linux系统篇】:Linux线程同步---条件变量,信号量与CP模型实现
  • Python cv2形态学操作:从基础原理到实战应用
  • 《AI大模型应知应会100篇》第49篇:大模型应用的成本控制策略
  • Python之pip图形化(GUI界面)辅助管理工具
  • 校内周赛题(思维题)
  • 代码随想录算法训练营第60期第二十八天打卡
  • 系统架构师2025年论文《论软件系统架构评估及其应用》
  • TS 泛型
  • 网络的搭建
  • SSTI学习
  • 系统思考:选择大于努力
  • AI Agent(4):Agent核心技术栈
  • VTK|结合qt创建通用按钮控制显隐(边框、坐标轴、点线面)
  • 【原创】批量区分横屏竖屏照片
  • 云计算与大数据进阶 | 25、可扩展系统构建