关于const应用与const中的c++陷阱

目录

const在不同位置的作用

[int *const pt 的含义](#int *const pt 的含义)

[const int *pt 的含义:](#const int *pt 的含义:)

[int *const pt与const int *pt 区别](#int *const pt与const int *pt 区别)

[const int *pt(pt指向一个const int)](#const int *pt(pt指向一个const int))

[int *const pt](#int *const pt)

C++陷阱:多级指针的const匹配

[疑问:为什么在一级间接关系 非const指针可以赋值给const指针](#疑问:为什么在一级间接关系 非const指针可以赋值给const指针)


const在不同位置的作用

int *const pt 的含义

pt 是一个指向常量整数的指针

const 修饰的是 pt 本身,不是 pt 指向的数据

这意味着:pt 不能改变指向 (不能指向其他地址)但可以通过 pt 修改指向的数据

const int *pt 的含义:

pt 是一个指向常量整数的指针

const 修饰的是pt指向的数据

这意味着:通过 pt 不能修改 它指向的数据 但 pt 本身可以改变指向(指向其他地址)

int *const pt与const int *pt 区别

const int *pt(pt指向一个const int)

cpp 复制代码
#include <iostream>
int main()
{
    using namespace std;
    int age =20;
    int *pd =&age;
    const int *pt =pd;
    cout<<"pt的值"<<*pt<<endl;
    cout<<"age的地址"<<&age<<endl;
    cout<<"pt指向的地址"<<pt<<endl;
    age=19;//通过更改age的值
    cout<<"更改后pt的值"<<*pt<<endl;
    cout<<"更改后age的地址"<<&age<<endl;
    cout<<"更改后pt指向的地址"<<pt<<endl;
    int agge=18;//更改pt的地址
    pt =&agge;
    cout<<"更改地址后pt的值"<<*pt<<endl;
    cout<<"agge的地址"<<&agge<<endl;
    cout<<"更改地址后pt指向的地址"<<pt<<endl;
    return 0;
    
}

输出的结果如下

通过观察输出的结果可以发现 在const int* pt中 pt可以通过修改其指向的地址来更改数据 同时也可以借助更改开始指向age的值来更改数据

int *const pt

cpp 复制代码
#include <iostream>
int main()
{
    using namespace std;
    int age =20;
    int *pd =&age;
    int *const pt =pd;
    cout<<"pt的值"<<*pt<<endl;
    cout<<"age的地址"<<&age<<endl;
    cout<<"pt指向的地址"<<pt<<endl;
    age =21;
    cout<<"更改后pt的值"<<*pt<<endl;
    cout<<"更改后age的地址"<<&age<<endl;
    cout<<"更改后pt指向的地址"<<pt<<endl;
    /*
    pt =&agge;
    cout<<"更改地址后pt的值"<<*pt<<endl;
    cout<<"agge的地址"<<&agge<<endl;
    cout<<"更改地址后pt指向的地址"<<pt<<endl;
    */
    //注意/**/中的代码会报错
    return 0;
}

注意上述代码后面/**/中的代码会报错 其报错的原因即可以证明出在int *const pt中 const修饰是pt本身 故其不可以更改其指向的地址 上述代码通过其开始修改age(其开始指向的地址)从而更改其值

C++陷阱:多级指针的const匹配

cpp 复制代码
#include <iostream>
int main()
{
    using namespace std;
    const int **pp2;
    int *pl;
    const int n =13;
    pp2= &pl;
    *pp2=&n;
    *pl=10;
    cout<<**pp2;
    return 0;
}

上述代码输出结果:error: assigning to 'const int **' from incompatible type 'int **'

pp2= &pl;

^~~

1 error generated.

为什么上述代码会发生报错 其根本原因在于其犯了"非const指针赋值给const指针"

如果允许上述代码运行 观察下述

cpp 复制代码
const int **pp2;
int *pl;
const int n = 13;

pp2 = &pl;      // 如果允许这个
*pp2 = &n;      // 那么*pp2(即pl)现在指向const的n
*pl = 10;       // 通过非const指针pl修改了const变量n!违反const原则

pp2指向pl的地址(即pp2存储的是pl变量的地址)

->通过pp2解引用访问pl,让pl指向n的地址

->通过pl解引用访问n,将n的值修改为10

**其行为违反const的原则:**const指针承诺不修改所指向的对象,如果我们允许将非const指针(即可以修改所指向对象的指针)赋值给const指针,那么通过这个const指针我们虽然不会修改对象,但是原来的非const指针仍然可以修改对象,这实际上破坏了const指针所做的承诺(即指向的对象不会被修改)。

疑问:为什么在一级间接关系 非const指针可以赋值给const指针

int* p1;

const int* p2 = p1;

观察上述发现 其实其是通过p2来进行访问p1的

其根本原因是因为其权限不同

源指针 (int*):具有读写权限

目标指针 (const int*):只有读权限

即p1将地址传给p2 由于const int*的限制 其只有读权限 无法对地址的值进行修改

感谢阅读

相关推荐
2401_892070981 天前
【Linux C++ 日志系统实战】LogFile 日志文件管理核心:滚动策略、线程安全与方法全解析
linux·c++·日志系统·日志滚动
yuzhuanhei1 天前
Visual Studio 配置C++opencv
c++·学习·visual studio
不爱吃炸鸡柳1 天前
C++ STL list 超详细解析:从接口使用到模拟实现
开发语言·c++·list
十五年专注C++开发1 天前
RTTR: 一款MIT 协议开源的 C++ 运行时反射库
开发语言·c++·反射
‎ദ്ദിᵔ.˛.ᵔ₎1 天前
STL 栈 队列
开发语言·c++
2401_892070981 天前
【Linux C++ 日志系统实战】高性能文件写入 AppendFile 核心方法解析
linux·c++·日志系统·文件写对象
郭涤生1 天前
STL vector 扩容机制与自定义内存分配器设计分析
c++·算法
༾冬瓜大侠༿1 天前
vector
c语言·开发语言·数据结构·c++·算法
cccyi71 天前
【C++ 脚手架】etcd 的介绍与使用
c++·服务发现·etcd·服务注册
liu****1 天前
第16届省赛蓝桥杯大赛C/C++大学B组(京津冀)
开发语言·数据结构·c++·算法·蓝桥杯