热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MoreEffectiveC++第一讲,指针和引用

1.指针和引用的区别相同点:指针和引用都是让你间接引用其它对象。不同点:1.引用:声明时必须初始化,并且以后不能改变&#x
1. 指针和引用的区别
  • 相同点:指针和引用都是让你间接引用其它对象。
  • 不同点:
  • 1.引用:声明时必须初始化,并且以后不能改变(即不能给引用重新赋值),但是指定的对象其内容可以改变。
    指针:声明可以不初始化,并且可以被重新赋值以指向另一个不同的对象
  • 2.从内存分配上看,程序为指针变量分配内存区域,而不为引用分配内存区域。
  • 3.不存在指向空值的引用这个事实。
  • 4.引用比指针更安全。由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,因此引用很安全。对于指针来说,它可以随时指向别的对象,并且可以不被初始化,或为NULL,所以不安全。
  • 5.引用的大小是所指向的变量的大小,因为引用只是一个别名而已;指针是指针(地址)本身的大小,32位系统下,一般为4个字节。

//指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。//但是引用则总是指向在初始化时被指定的对象,以后不能改变。std::string s1("Nancy");std::string s2("Clancy");std::string& rs = s1; // rs引用s1std::string* ps = &s1; // ps指向s1rs = s2; // rs仍旧引用s1,但是s1的值现在是"Clancy"

1.1 常量指针和指针常量

1.1.1 常量指针

解释:const int *PtrConst 或者是 int const PtrConst (即const 在的左边)
常量指针就是指向常量的指针,但是这里指的“常量”是在解引用时起到所谓常量的作用,并非是指向的变量就是常量,指向的变量既可以是非常量也可以是常量。总体意思是不能修改指向某变量的值。
功能:让指针指向一个常量,可以防止使用指针来修改所指向的值。

注意点:
1.常量指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改;

int a &#61; 1;const int *p &#61; &a;cout << *p << a << std::endl; //此时这两个值应该是相等的 *p&#61;a&#61;1a &#61; 2;//可以&#xff0c;可以通过原来的声明来修改*p &#61; 3; //报错&#xff0c;不可以&#xff0c;不能通过指针来修改指向的对象cout<< *p << a << std::endl;// *p&#61;a&#61;2

因为不能通过这个指针来修改&#xff0c;所以可以用常量指针当函数的参数使用。
2. 常量指针还可以指向别处&#xff0c;因为指针本身只是个变量&#xff0c;只不过指向的对象是所谓的"常量"&#xff0c;可以指向任意地址&#xff1b;

int a &#61; 1;const int *p &#61; &a; //指针指向acout << "p&#61; "<< *p <<";" << "a&#61;" << a << std::endl; // p&#61;a&#61;1int b &#61; 2;p &#61; &b; //指针指向bcout<<"p&#61; "<< *p << ";" <<"b&#61;" << b<< std::endl; //p&#61;b&#61;2

3.可以将const 变量的地址赋给指向const 的指针&#xff08;即常量指针)。但是不可以将const 的地址赋给常规指针&#xff0c;除非使用强制类型转换&#xff0c;const_cast

const int a &#61; 1; //const修饰的变量const int * p &#61; &a; //可以const int a &#61; 1; //const修饰的变量int * p &#61; &a; //常规指针&#xff0c;不可以const int a &#61; 1;int *p &#61; const_cast<int*>(&a) //可以

1.1.2 指针常量

int const *PtrConst;
本质是一个常量&#xff0c;而用指针修饰它。指针常量的值是指针。
1.必须初始化&#xff0c;只能指向一个变量&#xff0c;绝不可再改变指向另一个变量

int *const ConstPtr;//报错&#xff0c;error C2734: “ConstPtr”: 如果不是外部的&#xff0c;则必须初始化常量对象int a&#61;1; int *const ConstPtr&#61;&a; //可以&#xff0c;目前是只指向这一个变量int b &#61; 2; ConstPtr&#61;&b; //不可以&#xff0c;不可以在改变指针的指向了&#xff01;只能指向另一个变量

2.指向的地址所对应的内容可以变化

int a&#61;1; int *const ConstPtr&#61;&a; ConstPtr &#61; 3; //可以

如果出现在星号两边&#xff0c;表示被指物和指针都是常量。

1.2 常量引用用法

常量引用”其实是**“对 const 的引用”**的简称。因此不可以通过该引用来修改它所指向的对象的值。

  1. 指向常量对象时&#xff0c;一定要使用“常量引用”&#xff0c;而不能是一般的引用。

const int ci &#61; 1024;
const int &r1 &#61; ci; // 正确&#xff1a;引用及其对应的对象都是常量
int &r2 &#61; ci; // 错误&#xff1a;试图让一个非常量引用指向一个常量对象

  1. 指向非常量对象时&#xff0c;也可以用“常量引用”&#xff0c;但不允许用该引用修改非常量对象的值。
    “常量引用”仅对引用可参与的操作做出了限定&#xff0c;对于引用的对象本身是不是一个常量未作限定。
    因为对象也可能是个非常量&#xff0c;所以允许通过其他途径改变它的值&#xff1a;

int i &#61; 42;
int & r1 &#61; i; // 普通引用指向非常量对象 i
const int & r2 &#61; i; // 常量引用也绑定非常量对象 i
r1 &#61; 40; // 正确&#xff0c;r1并非常量引用 r1 &#61; i &#61; 42
r2 &#61; 0; // 错误&#xff0c;r2是一个常量引用

  1. 引用的类型必须和所引用的类型严格匹配&#xff0c;且不能与字面值或者某个表达式的计算结果绑定在一起&#xff0c;
    但是 “常量引用” 是例外&#xff08;只要被引用的类型能够转换为常量引用的类型&#xff09;。

int i &#61; 42;
const int &r1 &#61; i; // 正确&#xff1a;指向非常量对象
const int &r2 &#61; 42; // 正确&#xff1a;r2 是一个常量引用
const int &r3 &#61; r1 * 2; // 正确&#xff1a;r3 是一个常量引用
int &r4 &#61; r1 * 2; // 错误&#xff1a;r4 是一个普通的非常量引用

int i &#61; 40;int &r1 &#61; i; // 普通引用r1 指向 i const int &r3 &#61; i * 2; // 常量引用r3 指向 2icout << "r3 &#61; " << r3 << std::endl; // r3 &#61; 80r1 &#61; 30; //普通引用改变了 i 的值&#xff0c; i &#61; 30cout << "r3 &#61; " << r3 << " i &#61; " << i << std::endl;//测试r3是否改变. 依然没变 r3&#61;80

在这些情况下&#xff0c;“常量引用”实际上是绑定了一个临时量&#xff08;temporary&#xff09;对象。也就是说&#xff0c;允许“常量引用”指向一个临时量对象。
4. 在函数参数中&#xff0c;使用常量引用非常重要。因为函数有可能接受临时对象&#xff0c;而且同时需要禁止对所引用对象的一切修改。
5. 去掉常量的办法是调用const_cast函数


推荐阅读
  • KMP算法是处理字符串匹配的一种高效算法它首先用O(m)的时间对模板进行预处理,然后用O(n)的时间完成匹配。从渐进的意义上说,这样时间复 ... [详细]
  • 本文探讨了如何在Classic ASP中实现与PHP的hash_hmac('SHA256', $message, pack('H*', $secret))函数等效的哈希生成方法。通过分析不同实现方式及其产生的差异,提供了一种使用Microsoft .NET Framework的解决方案。 ... [详细]
  • 探讨ChatGPT在法律和版权方面的潜在风险及影响,分析其作为内容创造工具的合法性和合规性。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 由中科院自动化所、中科院大学及南昌大学联合研究提出了一种新颖的双路径生成对抗网络(TP-GAN),该技术能通过单一侧面照片生成逼真的正面人脸图像,显著提升了不同姿态下的人脸识别效果。 ... [详细]
  • 本文将详细探讨 Java 中提供的不可变集合(如 `Collections.unmodifiableXXX`)和同步集合(如 `Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。 ... [详细]
  • 使用JS、HTML5和C3创建自定义弹出窗口
    本文介绍如何结合JavaScript、HTML5和C3.js来实现一个功能丰富的自定义弹出窗口。通过具体的代码示例,详细讲解了实现过程中的关键步骤和技术要点。 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
  • CentOS 6.8 上安装 Oracle 10.2.0.1 的常见问题及解决方案
    本文记录了在 CentOS 6.8 系统上安装 Oracle 10.2.0.1 数据库时遇到的问题及解决方法,包括依赖库缺失、操作系统版本不兼容、用户权限不足等问题。 ... [详细]
  • 软件工程课堂测试2
    要做一个简单的保存网页界面,首先用jsp写出保存界面,本次界面比较简单,首先是三个提示语,后面是三个输入框,然 ... [详细]
  • 深入理解 JMeter 定时器
    本文详细介绍了JMeter中定时器的功能和使用方法,探讨了其在性能测试中的重要性,并结合实际案例解释了如何合理配置定时器以模拟真实的用户行为。文章还涵盖了定时器的执行顺序及其与其他元件的相互作用。 ... [详细]
  • 圆形进度指示器忽略宽度/高度属性并且不缩放 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • springMVC JRS303验证 ... [详细]
  • 本文介绍了一个经典的算法问题——活动选择问题,来源于牛客网的比赛题目。该问题要求从一系列活动集合中选出最多数量的相容活动,确保这些活动的时间段不重叠。 ... [详细]
author-avatar
手机用户2502863963
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有