热门标签 | 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函数


推荐阅读
  • 本文介绍了Java集合库的使用方法,包括如何方便地重复使用集合以及下溯造型的应用。通过使用集合库,可以方便地取用各种集合,并将其插入到自己的程序中。为了使集合能够重复使用,Java提供了一种通用类型,即Object类型。通过添加指向集合的对象句柄,可以实现对集合的重复使用。然而,由于集合只能容纳Object类型,当向集合中添加对象句柄时,会丢失其身份或标识信息。为了恢复其本来面貌,可以使用下溯造型。本文还介绍了Java 1.2集合库的特点和优势。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
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社区 版权所有