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


推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本题探讨了一种字符串变换方法,旨在判断两个给定的字符串是否可以通过特定的字母替换和位置交换操作相互转换。核心在于找到这些变换中的不变量,从而确定转换的可能性。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 本文介绍如何利用动态规划算法解决经典的0-1背包问题。通过具体实例和代码实现,详细解释了在给定容量的背包中选择若干物品以最大化总价值的过程。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
    本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
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社区 版权所有