看 C++ Primer 的58页, 讲拷贝时不能忽略 底层const这里的说的原因有点牵强, 这里给出自己的理解
extern const int ci =42;
const int * p2 = &ci;
extern const int *const p3= p2;
int *p= p3; //错,p没有底层const。
书上的解释是: p3是顶层const 也是底层const,拷贝p3可以不在乎其顶层const, 但是p3指向的是一个常量,因此不能用P3初始化p, 而p 只能指向非常量。 理解他说的意思是因为一个指向常量一个指向非常量。
但自己仔细想想, 底层const也可以指向一个非常量, 那是不是当p3一开始就用非常量初始化时,此时p3和p 都指向非常量了, int *p= p3; 是不是就正确了呢? 如果按书上的解释,给人的误解是当他俩都指向常量或非常量时就没问题了, 这是误解,产生误解是因为他没说清楚。
我是这么理解: 指向常量的指针既可以指向常量 也可以指向非常量, 而一般普通指针只能指向非常量。
1、假设 不同时具有底层const也可以拷贝:
当有底层const的指针给 没有底层const的指针赋值时, 因为 前者可以指向常量或非常量,后者只能指向非常量, 所以前者无关紧要。感觉没啥不对的。
现在反过来:
当没有底层const的指针 给 有底层const的指针 赋值时, 因为前者只能指向非常量, 后者可以指向常量或非常量,问题来了: 当后者指向非常量,都只需非常量了,至于能不能改变所指对象值,这是二者自身的语法规定问题,不相关; 但是当后者指向的是常量时, 因为前者只能指向非常量,
那把对象的地址赋值给你了,缺不能指向常量,这就矛盾了。 所以,因为在此时情况下不能同时满足双方语法规则。
所以干脆就规定赋值时二者必须具有底层const。 这样就规避了这种情况。 不管是不是这个原因这么规定的, 但是可以这么理解这个规定。
2、 或者我们这么理解: 指针int * 必须指向类型匹配的对象, 而指向常量的指针是const int * , 类型不匹配,所以不能拷贝, 也不能初始化。常量指针可以理解为值不变的指针
3、 或者这么理解也可以: 非常量可以转换为常量, 常量不可转换为非常量: int * 可以转换为 const int *, 反之不行。
不知道上面的三种理解是不是正确, 请理解真正原因的大神解疑答惑啊。
看 C++ Primer 的58页, 讲拷贝时不能忽略 底层const这里的说的原因有点牵强, 这里给出自己的理解的更多相关文章
- c++ primer 中讲的顶层const 和 底层 const 理解
c++ primer 中讲的 顶层const 和 底层 const 以前没搞懂的顶层const和底层const,这次看了后感觉明白了. 首先,const是一个限定符,被它修饰的变量的值不能改 ...
- 【C++ Primer | 15】构造函数与拷贝控制
合成拷贝控制与继承 #include <iostream> using namespace std; class Base { public: Base() { cout << ...
- c/c++ 拷贝控制 右值与const引用
拷贝控制 右值与const引用 背景:当一个函数的返回值是自定义类型时,调用侧用什么类型接收?? 1,如果自定义类型的拷贝构造函数的参数用const修饰了:可以用下面的方式接收. Test t2 = ...
- ASP.NET#使用母版时,如果要使用js中的getElementById()方法取得某个内容页的元素时要注意的问题
当使用母版,要使用js中的getElementById()方法取得某个内容页的元素时,所选取的id并不是母版中内容页的id,而是在设计内容页时设定的id例子:母版页: ...... <head ...
- msxml3.dll 执行页内操作时的错误
msxml3.dll 执行页内操作时的错误 regsvr32 msxml3.dll报错
- 请求通道在等待 00:00:58.9616639 以后答复时超时。增加传递给请求调用的超时值,或者增加绑定上的 SendTimeout 值。分配给此操作的时间可能是更长超时的一部分。
异常信息:请求通道在等待 00:00:58.9616639 以后答复时超时.增加传递给请求调用的超时值,或者增加绑定上的 SendTimeout 值.分配给此操作的时间可能是更长超时的一部分. 开发背 ...
- Linux - 几种方法来实现scp拷贝时无需输入密码
前言 在实际工作中,经常会将本地的一些文件传送到远程的机器上.scp是一个很好用的命令,缺点是需要手工输入密码. 如何在shell脚本中实现传输文件,而不用手工输入密码呢?接下来介绍三种方法. 一.建 ...
- BeanUtils.copyProperties()拷贝属性时,忽略空值
把source的属性值复制给target的相同属性上,注意:双方需要复制的属性要有get.set方法 BeanUtils.copyProperties(source, target, PublicUt ...
- 转载:看c++ primer 学习心得
学习C++ Primer时遇到的问题及解释 chenm91 感觉: l 啰嗦有时会掩盖主题:这本书确实有些啰嗦,比如在讲函数重载的时候,讲了太长一大段(有两节是打了*号的,看还是不看 ...
随机推荐
- 手动添加ubuntu服务
在/etc/init.d/目录下创建一个简单的服务脚本,假设脚本名为hello #!/bin/sh case "$1" in start) # start 的代码 ;; stop) ...
- [Luogu]中位数
Description Luogu1168 Solution 一种神奇的做法:开一个大根堆和小根堆,保证大根堆比小根堆多1个元素,且大根堆堆顶元素比小根堆堆顶元素小,那么大根堆堆顶就是中位数.插入的时 ...
- servlet中doGet()和doPost()的用法
转自:https://blog.csdn.net/qq_38963960/article/details/79468182 1.servlet中doGet()和doPost()的用法 一般来说我们是用 ...
- U盘拷贝目标文件过大无法复制时的解决方法
在cmd下输入:convert U盘符:/fs:ntfs ---> 回车 转换完成后可以看到U盘属性为NTFS了 这时就可以复制大文件到U盘了
- 自动构建自己的ASP.NET Core基础镜像
在开发过程中,我们可以根据自身情况来定制自己的基础镜像,以便加快CI\CD构建速度以及提高开发体验.这里我们就以ASP.NET Core的基础镜像为例来进行讲解. 本次教程代码见开源库:https:/ ...
- L2-2 小字辈
思路 bfs搜一下. 代码 #include <bits/stdc++.h> using namespace std; const int maxn=1e5+10; vector<i ...
- wamp修改MySQL密码
wamp默认密码为空 用户名为root: 左击wamp绿色小图标,打开phpMyAdmin ->执行 ->账号 ->找到用户名为root的修改权限&&点击修改权限 - ...
- EAC3 channel & program extension
EAC3 bit stream syntax允许在single bitstream中存在time-multiplexed substreams. 在EAC3的signle bitstream中,允许s ...
- springboot项目入门解析
config:主要用来存储配置文件,以及其他不怎么动用的信息. controller:项目的主要控制文件 dao: 主要用来操作数据库 entit ...
- Codeforces Global Round 3:B. Born This Way
Born This Way原文链接:[传送门] 题目大意:潇洒哥想乘坐飞机从A地到达C地,但是没有直达的航班,在A地和B地之间有一个可以中转的航班B,潇洒哥想早点到达C地(有航班就坐),但是很不幸他得 ...